I have a vector of strings and a method that is accepting [&str]. When I provide the strings as string literals everything works however when I try to build the same vector dynamically using Strings everything is failing.
Examples below:
//everything works fine.
let imports = vec!["import 1", "import 2"];
let import_selector = gtk::DropDown::from_strings(&imports);
//Throws an error
let mut imports = Vec::new(); // ive tried specifying the type here as Vec<&str> but it didn't help.
for imp in app_settings.lock().unwrap().imports.clone() {
let name = match imp.clone() {
Some(name) => name,
None => continue
};
if !imports.contains(&name) {
imports.push(name.as_str()); //I've tried this as &name giving the same result.
}
}
let import_selector = gtk::DropDown::from_strings(&imports);
//throws error: expected slice `[&str]`, found struct `Vec`
I think this is something to do with how I am passing the strings into the vector as I am passing String
and not a string literal however the Vector.push method seems to only accept String
.
How do I go about fixing this?
Adding a working example to demonstrate this issue:
use gtk::prelude::*;
use gtk::{CssProvider, StyleContext, Orientation};
use gtk::gdk::Display;
use libadwaita::{Application, ApplicationWindow};
use std::path::{Path, PathBuf};
use std::thread;
use std::fs;
use std::time::Duration;
const APP_ID: &str = "org.gtk_rs.HelloWorld2";
fn main() {
let app = Application::builder().application_id(APP_ID).build();
app.connect_activate(build_ui);
app.run();
}
pub fn build_ui(app: &Application) {
let imports = vec!["import 1", "import 2"];
let import_selector = gtk::DropDown::from_strings(&imports);
let imports_as_strings = Vec::new();
imports_as_strings.push(String::from("import 1"));
imports_as_strings.push(String::from("import 2"));
//Throws an error
let mut imports_2 = Vec::new(); // ive tried specifying the type here as Vec<&str> but it didn't help.
for imp in imports_as_strings {
if !imports_2.contains(&imp) {
imports_2.push(imp); //I've tried this as &name giving the same result.
}
}
let import_2_selector = gtk::DropDown::from_strings(&imports_2);
//throws error: expected slice `[&str]`, found struct `Vec`
let new_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
new_box.append(&import_selector);
new_box.append(&import_2_selector);
let window = ApplicationWindow::builder()
.application(app)
.title("My GTK App")
.build();
// Present window
window.present();
}
I wasn't able to reproduce your issue, but I'm guessing you aren't actually trying this with as_str
and instead adding a reference. When you do that, you create a Vec<&String>
instead of a Vec<&str>
. If you simply add the type on this line:
let mut imports_2: Vec<&str> = Vec::new();
then you can guarantee this Vec
will always deref to &[&str]
This will move your error elsewhere, or allow type inference to fix it.
You can push &String
or &str
values and they will be deref-ed to &str
. If you try to push String
, you will be told to add a reference.
imports.push(&name);
Doing as_str
should always work.
imports.push(name.as_str());