0

This working Rust code repeats itself somewhat:

fn append_column(tree: &TreeView, attribute: &str, id: i32) {
    let column = TreeViewColumn::new();
    match attribute {
        "text" => {
            let cell = CellRendererText::new();    
            TreeViewColumnExt::pack_start(&column, &cell, true);
            TreeViewColumnExt::add_attribute(&column, &cell, attribute, id);
        }
        "pixbuf" => {
            let cell = CellRendererPixbuf::new();
            TreeViewColumnExt::pack_start(&column, &cell, true);
            TreeViewColumnExt::add_attribute(&column, &cell, attribute, id);
        }
        _ => { panic!("Unexpected attribute") }
    }
    tree.append_column(&column);
}

I've tried to simplify it using downcast() as follows:

fn append_column(tree: &TreeView, attribute: &str, id: i32) {
    let column = TreeViewColumn::new();
    let cell : CellRenderer;
    match attribute {
        "text" => { cell = CellRendererText::new().downcast::<CellRenderer>().unwrap() }
        "pixbuf" => { cell = CellRendererPixbuf::new().downcast::<CellRenderer>().unwrap() }
        _ => { panic!("Unexpected attribute") }
    }
    TreeViewColumnExt::pack_start(&column, &cell, true);
    TreeViewColumnExt::add_attribute(&column, &cell, attribute, id);
    tree.append_column(&column);
}

but I get the follow errors:

error[E0277]: the trait bound `CellRenderer: IsA<CellRendererText>` is not satisfied
   --> src/main.rs:23:52
    |
23  |         "text" => { cell = CellRendererText::new().downcast::<CellRenderer>().unwrap() }
    |                                                    ^^^^^^^^ the trait `IsA<CellRendererText>` is not implemented for `CellRenderer`

Can I remove the duplication?

DobbyTheElf
  • 604
  • 6
  • 21
  • 2
    This question is lacking context. What are the types involved? Please give a reproducible code, or at least enough context for us to understand the code. – Chayim Friedman Dec 30 '22 at 10:18
  • Please provide a [MRE]. Also look at further [Rust-specific MRE tips](https://stackoverflow.com/tags/rust/info). – Finomnis Dec 30 '22 at 10:21
  • 1
    Why not extract the code to a function? – Chayim Friedman Dec 30 '22 at 10:24
  • 1
    You want [`upcast`](https://docs.rs/glib/0.16.7/glib/object/trait.Cast.html#method.upcast) here, not `downcast` – Jmb Dec 30 '22 at 11:04
  • @Chayim Friedman I did think about using a function, but with the boilerplate for the function, the total result would have been longer, not shorter. – DobbyTheElf Dec 30 '22 at 15:00

1 Answers1

1

As Jmb noted you want to use upcast instead of downcast after which your code can be written as:

use gtk::{
    prelude::*, CellRenderer, CellRendererPixbuf, CellRendererText, TreeView, TreeViewColumn,
};

fn append_column(tree: &TreeView, attribute: &str, id: i32) {
    let column = TreeViewColumn::new();
    let cell: CellRenderer = match attribute {
        "text" => CellRendererText::new().upcast(),
        "pixbuf" => CellRendererPixbuf::new().upcast(),
        _ => panic!("Unexpected attribute"),

    };
    TreeViewColumnExt::pack_start(&column, &cell, true);
    TreeViewColumnExt::add_attribute(&column, &cell, attribute, id);
    tree.append_column(&column);
}
cafce25
  • 15,907
  • 4
  • 25
  • 31