0

I am learning to using rust to do some work. I am using this code to find element from Vec in rust:

let filtered_music:Vec<Music> = musics.iter()
            .filter(|item| item.source_id == fav.source_id)
            .collect();

the next step I want to put he element to another object:

let curr_music = &filtered_music[0];
let fav_resp = FavMusicResponse{
    id: (&fav.id.to_string()).parse().unwrap(),
    song_id: None,
    created_time: 0,
    updated_time: 0,
    user_id: 0,
    source_id: fav.source_id.to_string(),
    like_status: 0,
    source: 0,
    playlist_id: 0,
    play_count: 0,
    fetched_download_url: None,
    downloaded: None,
    music: curr_music
};

but the compiler tell me expected Music, found &Music , what should I do to fix it? This is my minimal example about this problem that could run in https://play.rust-lang.org/ to reproduce this situation:

fn main() {
    println!("Hello, world!");
    let musics:Vec<Music> = Vec::new();
    let filtered_music:Vec<&Music> = musics.into_iter()
            .filter(|item| item.source_id == "1")
            .collect();
    let resp = MusicRes{
        music: filtered_music[0]
    };
}


pub struct Music {
    pub id: i64,
    pub name: String,
    pub artists: String,
    pub album_id: i64,
    pub publishtime: i64,
    pub status: i32,
    pub duration: i32,
    pub source_id: String,
    pub source: i32,
    pub created_time: i64,
    pub updated_time:i64,
    pub album: String,
    pub fetched_download_url: i32
}

pub struct MusicRes {
    pub music:Music
}
mkrieger1
  • 19,194
  • 5
  • 54
  • 65
Dolphin
  • 29,069
  • 61
  • 260
  • 539

1 Answers1

0

Here are the major changes

fn take<T>(mut vec: Vec<T>, index: usize) -> Option<T> {
    if index < vec.len() {
        Some(vec.swap_remove(index))
    } else {
        None
    }
}
fn main() {
    println!("Hello, world!");
    let musics: Vec<Music> = Vec::new();
    let filtered_music: Vec<Music> = musics
        .into_iter()
        .filter(|item| item.source_id == "1")
        .collect();
    let resp = MusicRes {
        music: take(filtered_music, 0).unwrap(),
    };
}

Edit

If you just want the first element of your music vector, consider using .next() after filtering. This would avoid the take function.

My answer is based on this answer

Here is a working example: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=6d4137ccb7f737fa6261ea8c27bd012b

Njuguna Mureithi
  • 3,506
  • 1
  • 21
  • 41