console-rs/console

Make more use of `Read` and `Write`

felipesere opened this issue ยท 5 comments

Creating a Term from Read and Write was added in #34 (merged #93 ) which is pretty cool ๐ŸŽ‰
I am using that mechanism to write a TestTerminal that buffers calls to Write internally and has prepared content for Read.

My code uses term.read_line() though, which to my surprise uses stdin() directly.
I was expecting that to go through Read.

Is that something that could be adjusted? I can probably try and submit a PR?

@felipesere I just noticed that the read field of a ReadWrite pair is currently not used at all. To me (just an outsider, not a maintainer), that feels like an oversight and your patch seems like a natural completion of the work in #93.

Sorry for the late reply but I would welcome a PR.

Attempted fix at #123. I couldn't test that easily. @felipesere If you get the chance to do so, your feedback would be very welcome.

(Besides, I would be interested in your setup for the TestTerminal crate: I'm interested in testing some changes to the dialoguer crate; sounds like your setup fits my use case. Any chance you can share something about this?)

@pksunkara Any news on this? This an essential feature in my application. I could continue working on this if you comment on the pr?

As far as I can tell these are the lines using stdin:

These ones seems problematic as well:

I would check if we have a ReadWritePair and use the reader. Otherwise the functions above. Does that sound right?

What about implementing these four functions for the TermTarget Enum:

impl TermTarget {
    fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
        if let TermTarget::ReadWritePair(pair) = self {
            todo!()
        } else {
            io::stdin().read(buf)
        }
    }
    fn read_line(&self, buf: &mut String) -> io::Result<usize> {
        if let TermTarget::ReadWritePair(pair) = self {
            todo!()
        } else {
            io::stdin().read_line(buf)
        }
    }
    fn read_secure(&self, buf: &mut &[u8]) -> io::Result<String> {
        if let TermTarget::ReadWritePair(pair) = self {
            todo!()
        } else {
            read_secure()
        }
    }
    fn read_single_key(&self, buf: &mut &[u8]) -> io::Result<Key> {
        if let TermTarget::ReadWritePair(pair) = self {
            todo!()
        } else {
            read_single_key()
        }
    }
}

Then we do not need to worry about any checking in the Term struct

I would welcome a PR here. But, I haven't been focusing on maintaining console anymore. So, you will have to wait for mitsuhiko to review