cyucelen / marker

🖍️ Marker is the easiest way to match and mark strings for colorful terminal outputs!
MIT License
47 stars 13 forks source link

MarkWriter implementation #27

Open Darkclainer opened 4 years ago

Darkclainer commented 4 years ago

This is branch of issue #17.

Context

I recap the idea. We want to make wrapper for io.Writer interface, that colorize its input. For example we want to colorize our log output. If we have this wrapper, we simply do:

log.SetOutput(NewMarkWriter(os.stdout, rules))

I've seen the PR #24 with implementation for such wrapper and I sure it works in that context (for Logger), but can have subtle bugs in others.

Problem

Writing in common can happen in parts. We can write on part of line, than - another. It's undefined how we use io.Writer and this is the reason, why it can not nicely live with Mark. Mark have some rules, even regex and etc. It need full text to work correctly. Imagine that we writer our line in io.Writer by single byte - Mark will not work. If we match word "sense", and write:

MarkWriter.Write("se")
MarkWriter.Write("nse")

MarkWriter will not match "sense". I hope I made problem clear.

It's not like we can do nothing to mitigate this issue, but the way that I see has its own drawbacks. We can buffer and collect our line of text in MarkWriter until we get some delimiter (newline makes sense). So

MarkWriter.Write("se")
MarkWriter.Write("nse")
MarkWriter.Write(" blabla\n")

now can mark "sense", but will write entire string in it's underlying io.Writer.

And there is another thing - we should implement Close method, that will flush buffer and close underlying Writer (if it can be close of course).

jnatalzia commented 4 years ago

This is a great point - streaming data could def run into this. When implementing I think a helper function or a default delimeter of \n could be great here.