How can I transform my calendar into a widget with the iced crate

I created a calendar with the iced gui crate. How can I make this a widget, so I can spawn multiple calendars?
I couldn't understand the examples as it doesn't use other elements, it renders a circle or a canvas and not another widget like buttons and text.

/// # How the `iced` library works:
/// 
/// Iced expects the following structure:
///
/// - State: the current data of the application
/// - Messages: events that trigger the update of the state
/// - View logic: widgets or components
/// - Update logic: how the message operate on the state

// States for the elemtns
use iced::{button};
// The elements to use
use iced::{Element, Button, Column, Row, Text, Container, Rule};
// Styling options
use iced::{HorizontalAlignment, Align, Length};
// The application settings
use iced::{Settings, Application, executor, Command};

use time;

/// This is the state of the application. In here we store the current count.
struct Calendar {
    day: u8,
    month: u8,
    year: i32,

    // Buttons handler that manipulate the counter
    // this is the local state of the buttons
    previous_month_button: button::State,
    next_month_button: button::State,
}

/// The events that will trigger changes on the ui or on the data
#[derive(Debug, Clone, Copy)]
pub enum Message {
    PreviousMonth,
    NextMonth,
}

impl Application for Calendar {
    type Message = Message;
    type Executor = executor::Default;
    type Flags = ();

    /// Default settings when starting the GUI
    fn new(_flags: ()) -> (Self, Command<Message>) {
        let now = time::Date::today();
        let day = now.day();
        let month = now.month();
        let year = now.year();
       
        (
            Self {
                day,
                month,
                year,
                previous_month_button: Default::default(),
                next_month_button: Default::default()
            },
            Command::none()
        )
    }

    /// The title of the window
    fn title(&self) -> String {
        String::from("Calendar")
    }
    
    // The view logic where we define the gui
    fn view(&mut self) -> Element<Message> {
        let days = vec!["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
        let months = vec!["January", "February", "March", "April", "May", "June",
                          "July", "August", "September", "October", "November", "December"];

        let month = Text::new(months[(self.month as usize) - 1])
            .size(32)
            .color([0.6, 0.6, 0.6]);

        let year = Text::new(self.year.to_string())
            .size(32)
            .color([0.6, 0.6, 0.6]);

        // Create a header for the weekdays name
        let header: Row<Message> = days
            .iter()
            .enumerate()
            .fold(Row::new().spacing(25), |row, (_i, day)| {
                row.push(
                    Column::new()
                        .push(
                            Text::new(day.clone().to_string())
                                .size(25)
                        )
                        .align_items(Align::Center)
                        .width(Length::Fill)
                        .max_width(75)
                )
            });

        let mut calendar = Column::new()
        // Push the calendar month and year header
            .push(
                Row::new()
                    .push(
                        Row::new()
                            .push(month)
                            .push(year)
                            .spacing(12)
                            .width(Length::from(250))
                    )
                    .push(
                        Button::new(&mut self.previous_month_button,
                                    Text::new("<")
                                    .horizontal_alignment(HorizontalAlignment::Center)
                        )
                            .width(Length::from(65))
                            .on_press(Message::PreviousMonth)
                    )
                    .push(
                        Button::new(&mut self.next_month_button,
                                    Text::new(">")
                                    .horizontal_alignment(HorizontalAlignment::Center)
                        )
                            .width(Length::from(65))
                            .on_press(Message::NextMonth)
                    )
                    .padding(12)
                    .spacing(12)
                    .width(Length::Fill)
            )
        // Push the weekday header
            .push(header)
            .align_items(Align::Center);

        // Check the starting day of the selected month
        let month_start_day = time::Date::try_from_ymd(self.year, self.month, 1)
            .unwrap()
            .weekday()
            .number_from_sunday();

        // Keep track of the current day
        let mut day_count = 0;
        
        // Iterate over 6 weeks - months won't ocupy more than 6 weeks
        for _ in 0..6 {
            let mut week = Row::new();

            // Iterate over all the weekdays, starting from sunday
            for weekday_num in 1..8 {
                if month_start_day == weekday_num || day_count >= 1
                {
                    day_count += 1;
                    
                    if time::Date::try_from_ymd(self.year, self.month, day_count).is_ok() {
                        week = week.push(
                            Column::new()
                                .push(
                                    Text::new(day_count.to_string())
                                )
                                .align_items(Align::Center)
                                .width(Length::Fill)
                        )
                            .spacing(25);
                    } else {
                        week = week.push(
                            Column::new()
                                .push(
                                    Text::new("")
                                )
                                .align_items(Align::Center)
                                .width(Length::Fill)
                        )
                            .spacing(25);
                    }
                } else {
                    week = week.push(
                        Column::new()
                            .push(
                                Text::new("")
                            )
                            .align_items(Align::Center)
                            .width(Length::Fill)
                    )
                        .spacing(25);
                }
            }

            calendar = calendar.push(week);
        }
        
        let calendar_container = Container::new(calendar)
            .width(Length::Fill)
            .height(Length::Fill)
            .center_x()
            .center_y()
            .into();

        calendar_container
    }

    // The update logic
    fn update(&mut self, message: Message) -> Command<Message> {
        match message {
            Message::PreviousMonth => {
                if self.month <= 1 {
                    self.month = 12;
                    self.year -= 1;
                } else {
                    self.month -= 1
                }
                Command::none()
            }
            Message::NextMonth => {
                if self.month >= 12 {
                    self.month = 1;
                    self.year += 1;
                } else {
                    self.month += 1;
                }
                Command::none()
            }
        }
    }
}

fn main() {
    Calendar::run(Settings::default()).unwrap();
}

To solve this issue I did the following:

  1. In the application Struct I added a field called Calendars that take a Vec<Calendar>;
  2. In the application Message enum, I added a CalendarMessage that takes an index and a CalendarMessage - this is done to choose the right calendar in the Vec and to pass a message
  3. iter_mut over all the calendars and map a message with the index and the CalendarMessage.

Here is the full code:

widgets.rs

pub mod calendar;

/widgets/calendar.rs

// States for the elements
use iced::{button};
// The elements to use
use iced::{Element, Button, Column, Row, Text, Container};
// Styling options
use iced::{HorizontalAlignment, Align, Length};
// The application settings
use iced::{Settings, Application, executor, Command};

use time;

/// This is the state of the application. In here we store the current count.
#[derive(Debug, Clone, Copy)]
pub struct Calendar {
    day: u8,
    month: u8,
    year: i32,

    // Buttons handler that manipulate the counter
    // this is the local state of the buttons
    previous_month_button: button::State,
    next_month_button: button::State,
}

/// The events that will trigger changes on the calendar
#[derive(Debug, Clone, Copy)]
pub enum CalendarMessage {
    PreviousMonth,
    NextMonth,
}

impl Calendar {
    /// Default settings when starting the GUI
    pub fn new() -> Self {
        let now = time::Date::today();
        let day = now.day();
        let month = now.month();
        let year = now.year();
        
        Self {
            day,
            month,
            year,
            previous_month_button: Default::default(),
            next_month_button: Default::default()
        }
    }

    // The view logic where we define the gui
    pub fn view(&mut self) -> Element<CalendarMessage> {
        let days = vec!["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
        let months = vec!["January", "February", "March", "April", "May", "June",
                          "July", "August", "September", "October", "November", "December"];

        let month = Text::new(months[(self.month as usize) - 1])
            .size(32)
            .color([0.6, 0.6, 0.6]);

        let year = Text::new(self.year.to_string())
            .size(32)
            .color([0.6, 0.6, 0.6]);

        // Create a header for the weekdays name
        let header: Row<CalendarMessage> = days
            .iter()
            .enumerate()
            .fold(Row::new().spacing(25), |row, (_i, day)| {
                row.push(
                    Column::new()
                        .push(
                            Text::new(day.to_string())
                                .size(25)
                        )
                        .align_items(Align::Center)
                        .width(Length::Fill)
                        .max_width(75)
                )
            });

        let mut calendar = Column::new()
        // Push the calendar month and year header
            .push(
                Row::new()
                    .push(
                        Row::new()
                            .push(month)
                            .push(year)
                            .spacing(12)
                            .width(Length::from(250))
                    )
                    .push(
                        Button::new(&mut self.previous_month_button,
                                    Text::new("<")
                                    .horizontal_alignment(HorizontalAlignment::Center)
                        )
                            .width(Length::from(65))
                            .on_press(CalendarMessage::PreviousMonth)
                    )
                    .push(
                        Button::new(&mut self.next_month_button,
                                    Text::new(">")
                                    .horizontal_alignment(HorizontalAlignment::Center)
                        )
                            .width(Length::from(65))
                            .on_press(CalendarMessage::NextMonth)
                    )
                    .padding(12)
                    .spacing(12)
                    .width(Length::Fill)
            )
        // Push the weekday header
            .push(header)
            .align_items(Align::Center);

        // Check the starting day of the selected month
        let month_start_day = time::Date::try_from_ymd(self.year, self.month, 1)
            .unwrap()
            .weekday()
            .number_from_sunday();

        // Keep track of the current day
        let mut day_count = 0;
        
        // Iterate over 6 weeks - months won't ocupy more than 6 weeks
        for _ in 0..6 {
            let mut week = Row::new();

            // Iterate over all the weekdays, starting from sunday
            for weekday_num in 1..8 {
                if month_start_day == weekday_num || day_count >= 1
                {
                    day_count += 1;
                    
                    if time::Date::try_from_ymd(self.year, self.month, day_count).is_ok() {
                        week = week.push(
                            Column::new()
                                .push(
                                    Text::new(day_count.to_string())
                                )
                                .align_items(Align::Center)
                                .width(Length::Fill)
                        )
                            .spacing(25);
                    } else {
                        week = week.push(
                            Column::new()
                                .push(
                                    Text::new("")
                                )
                                .align_items(Align::Center)
                                .width(Length::Fill)
                        )
                            .spacing(25);
                    }
                } else {
                    week = week.push(
                        Column::new()
                            .push(
                                Text::new("")
                            )
                            .align_items(Align::Center)
                            .width(Length::Fill)
                    )
                        .spacing(25);
                }
            }

            calendar = calendar.push(week);
        }
        
        Container::new(calendar)
            .width(Length::Fill)
            .height(Length::Fill)
            .center_x()
            .center_y()
            .into()
    }

    // The update logic
    pub fn update(&mut self, message: CalendarMessage) -> Command<CalendarMessage> {
        match message {
            CalendarMessage::PreviousMonth => {
                if self.month <= 1 {
                    self.month = 12;
                    self.year -= 1;
                } else {
                    self.month -= 1
                }
                Command::none()
            }
            CalendarMessage::NextMonth => {
                if self.month >= 12 {
                    self.month = 1;
                    self.year += 1;
                } else {
                    self.month += 1;
                }
                Command::none()
            }
        }
    }
}

main.rs

struct App {
    calendars: Vec<Calendar>
}

#[derive(Debug, Clone, Copy)]
enum AppMessage {
    CalendarMessage(usize, CalendarMessage)
}

impl Application for App {
    type Message = AppMessage;
    type Executor = executor::Default;
    type Flags = ();

    /// Default settings when starting the GUI
    fn new(_flags: ()) -> (Self, Command<AppMessage>) {
        // Create 3 calendars
        let calendar = Calendar::new();
        let mut calendars = Vec::new();
        calendars.push(calendar);
        calendars.push(calendar);
        calendars.push(calendar);
        
        (
            Self {calendars},
            Command::none()
        )
    }

    /// The title of the window
    fn title(&self) -> String {
        String::from("Calendar")
    }
    
    // The view logic where we define the gui
    fn view(&mut self) -> Element<AppMessage> {
        let calendars = self.calendars
            .iter_mut()
            .enumerate()
            .fold(Column::new(), |column, (i, cal)| {
                column.push(cal.view().map(move |message| {AppMessage::CalendarMessage(i, message)}))
            });

        let content = Column::new()
            .push(Text::new("Some random calendars"))
            .push(calendars);
        
        Container::new(content)
            .width(Length::Fill)
            .height(Length::Fill)
            .center_x()
            .center_y()
            .into()
    }

    // The update logic
    fn update(&mut self, message: AppMessage) -> Command<AppMessage> {
        match message {
            AppMessage::CalendarMessage(i, calendar_message) => {
                if let Some(calendar) = self.calendars.get_mut(i) {
                    calendar.update(calendar_message);
                }
                Command::none()
            },
        }
    }
}

fn main() {
    App::run(Settings::default()).unwrap();
}