With different widgets

Let's update the open() method to communicate with the playlist:

impl App {
    fn open(&self) {
        let file = show_open_dialog(&self.window);
        if let Some(file) = file {
            let ext = file.extension().map(|ext| ext.to_str().unwrap().to_string());
            if let Some(ext) = ext {
                match ext.as_str() {
                    "mp3" => self.playlist.emit(AddSong(file)),
                    "m3u" => self.playlist.emit(LoadSong(file)),
                    extension => {
                        let dialog = MessageDialog::new(Some(&self.window),  
DialogFlags::empty(), MessageType::Error, ButtonsType::Ok, &format!("Cannot open file with
extension . {}"
, extension)); dialog.run(); dialog.destroy(); }, } } } } }

So, we call the same emit() method to send a message to another widget:

self.playlist.emit(AddSong(file))

Here, we sent a message that is not yet handled by the Playlist (LoadSong), so let's fix that:

use m3u;

impl Playlist {
    fn load(&self, path: &Path) {
        let mut reader = m3u::Reader::open(path).unwrap();
        for entry in reader.entries() {
            if let Ok(m3u::Entry::Path(path)) = entry {
                self.add(&path);
            }
        }
    }
}

This method is called in the update() method:

fn update(&mut self, event: Msg) {
    match event {
        AddSong(path) => self.add(&path),
        LoadSong(path) => self.load(&path),
        NextSong => (),
        PauseSong => (),
        PlaySong => self.play(),
        PreviousSong => (),
        RemoveSong => (),
        SaveSong(path) => (),
        // To be listened by App.
        SongStarted(_) => (),
        StopSong => (),
    }
}