2

i am writing a program that uses text user interface, and i moved TUI functionality into the separate module, which contains a struct with TUI logic/variables.

So the declaration of struct is :

struct App<'a, T: io::Write>
where
    T: io::Write,
{
    items_left: StatefulList<String>,
    items_right: StatefulList<String>,
    input_mode: InputMode,
    parser: &'a parser::Parser,
    // --- [ Tui Backend ] ---
    backend: TermionBackend<T>,
}

and the constructor function implementation is :

impl<'a, T> App<'a, T>
where
    T: io::Write,
{
    fn new(parser: &'a parser::Parser) -> App<'a, T> {
        let stdout = io::stdout().into_raw_mode().unwrap();
        let stdout = MouseTerminal::from(stdout);
        let stdout = AlternateScreen::from(stdout);
        let backend = TermionBackend::new(stdout);
        let mut terminal = Terminal::new(backend).unwrap();
        let events = Events::new();

        App {
            items_left: StatefulList::with_items(vec![]),
            items_right: StatefulList::with_items(vec![]),
            input_mode: InputMode::Normal,
            parser,
            backend,
        }
}

But i got the error from rust-analyzer :

mismatched types expected struct TermionBackend<T> found struct TermionBackend<AlternateScreen<MouseTerminal<RawTerminal<Stdout>>>>

I want to use generics, because TermionBackend has a lot of nested classes in it, and its declaration is very huge.

Also i find out in sources that AlternateScreen struct, which is T, implements io::Write trait, and that's why i don't understand why the error occurs.

  • 1
    This doesn't look like an appropriate use of generics. What exactly are you trying to accomplish by being generic over `T`? – PitaJ Jan 18 '22 at 15:58
  • 1
    When you do `TermionBackend::new(stdout)`, `stdout` has a concrete type which is not (generic) `T`. You would need to receive that as input to `new()` for this to work (`T: io::Write` is not sufficient to actually create an instance of `T`). – Cruz Jean Jan 19 '22 at 00:38
  • 1
    @PitaJ , look at this gist : https://gist.github.com/xxxxxion/ba438aedef23091256624dc84c44dff7 . As I understand : "TermionBackend where T: Write ..." is expecting any type that implements io::Write -> AlternateScreen<...> satisfies this condition. The purpose is to shorten declaration. – thaiboy digital Jan 19 '22 at 10:16
  • Is `T` always the same type? If so, does [my answer](https://stackoverflow.com/a/70758568/5445670) work? – Solomon Ucko Jan 19 '22 at 12:55

1 Answers1

0

If you want to avoid typing the same type over and over, you can use a type alias, e.g. type T = AlternateScreen<MouseTerminal<RawTerminal<Stdout>>>.

Solomon Ucko
  • 5,724
  • 3
  • 24
  • 45