How to use use std::io::Write;

How to use use std::io::Write;
Getting errors on lines where its used.

impl io::Write for EditorContents {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
     
            match std::str::from_utf8(buf) {

                Ok(s) => {

                    self.content.push_str(s);
                    Ok(s.len())

                }
            
                Err(_) => Err(io::ErrorKind::WriteZero.into()),
            
            }
        }
    
        fn flush(&mut self) -> io::Result<()> {

            let out = write!(stdout(), "{}", self.content);
            stdout().flush()?;
            self.content.clear();
            out
        }    

Can you show us what the errors are? 90% of the time the error message explains what the problem is and will give you a hint for how to fix it.

1 Like

I have: use std::io::Write; at the top of my main.rs source code file.

If you are referring to the io module (e.g. -> io::Result<usize>) you will need to import it explicitly with something like use std::io.

2 Likes

I thought that by having 'use std::io::Write; that io would be available on its own as well.
But I see your point.

That just brings the Write trait into scope. If I wanted to import the io module as well I might write something like this:

use std::io::Write;
use std::io;

Or more succinctly,

use std::io::{self, Write};

You can also import std::io::Result and std::io::ErrorKind so you don't need to prefix them with io:: every time.

1 Like

Think I got it now.
Thanks.

1 Like

Is: use std::io::{write, result, errorkind}; valid ?

What does the compiler say when you try it?

Did not try it yet.

Anyway, I have a grip on things now.
Thanks.

I think in this case it'd say something about errorkind not existing, but there is something with a similar name.

In my experience, the Rust compiler is one of the best teachers you can have... For example, if I try that snippet on the playground I get this:

error[E0432]: unresolved imports `std::io::write`, `std::io::result`, `std::io::errorkind`
 --> src/lib.rs:1:15
  |
1 | use std::io::{write, result, errorkind};
  |               ^^^^^  ^^^^^^  ^^^^^^^^^ no `errorkind` in `io`
  |               |      |
  |               |      no `result` in `io`
  |               no `write` in `io`
  |
help: a macro with this name exists at the root of the crate
  |
1 | use std::{write, io::{result, errorkind}};
  |          ^^^^^^^^^   --                 ^^
help: a similar name exists in the module
  |
1 | use std::io::{write, Result, errorkind};
  |                      ^^^^^^
help: a similar name exists in the module
  |
1 | use std::io::{write, result, ErrorKind};
  |                              ^^^^^^^^^

So, better to import each explicitly or preface them with io::

Cleared the errors, now I get this. haven't seen this in other languages.


push and push_str would go in a separate impl block since they're not members of io::Write.

impl EditorContents {
    pub fn push(&mut self, ch: char) { ... }
    pub fn push_str(&mut self, string: &str) { ... }
}

impl io::Write for EditorContents {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> { ... }
    fn flush(&mut self) -> io::Result<()> { ... }
}
2 Likes

I thought you just import it and then you can use it anywhere without causing errors, this member thing might be a rustlang thing I dont know.

When implementing a trait you can only implement the methods for that trait inside the impl Write for MyType block.

If you want to attach other methods to your type then they go in their own impl MyType block.

It sounds like you learn by hacking on code and seeing how it goes, so you might want to check out Rust by Example. They've got a page on implementing methods.

https://doc.rust-lang.org/rust-by-example/fn/methods.html