Rust Iced Multiple Custom Subscriptions

I am having trouble understanding how to create a custom subscription on a page of an iced application which then feeds back to the main application subscription fn.
In the example below the solution is making the application simpler and single page.
For my use case I would have several subscriptions, some pages having multiple, others having one, and others having none. The example below is a simplified version of this.

pub fn main() -> iced::Result {
struct ProjectGui {
    soft_demo: SoftDemo

#[derive(Debug, Clone)]
enum Message {

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

    fn new(_flags: ()) -> (Self, Command<Message>) {
        Self {
            soft_demo: SoftDemo::default(),

    fn title(&self) -> String {
        String::from("ProjectGui - Iced")

    fn update(&mut self, message: Message) -> Command<Message> {
        match message {
            Message::SoftDemo(message) => {

    fn view(&self) -> Element<Message> {
        // Unrelated

    fn subscription(&self) -> Subscription<Message> {
        // This is where I do not know how to subscribe to subscriptions necessary 
        // for soft_demo. I have tried:
        if self.soft_demo.is_playing {
            time::every(Duration::from_millis(1000 / self.soft_demo.speed as u64)).map(Message::SoftDemo(SoftDemoMessage::Tick))
    // Associated Error:
error[E0308]: mismatched types
   --> src\
241 |                 .map(Message::SoftDemo(SoftDemoMessage::Tick(Instant::now())))
    |                  --- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected fn pointer, found enum `Message`
    |                  |
    |                  arguments to this method are incorrect
    = note: expected fn pointer `fn(std::time::Instant) -> Message`
                     found enum `Message`
note: associated function defined here
   --> C:\Users\workstation.local\.cargo\registry\src\\iced_futures-0.6.0\src\
89  |     pub fn map<A>(mut self, f: fn(O) -> A) -> Subscription<H, E, A>
    |            ^^^
pub struct SoftDemo {
    pub simulation: Simulation,
    pub is_playing: bool,
    pub queued_ticks: usize,
    pub speed: usize,
    pub next_speed: Option<usize>,
    pub version: usize,

#[derive(Debug, Clone)]
pub enum SoftDemoMessage {
    Simulation(SimulationMessage, usize),

impl<'a> SoftDemo {
    pub fn update(&mut self, message: SoftDemoMessage) -> Command<SoftDemoMessage> {
        match message {
            SoftDemoMessage::Simulation(message, version) => {
                if version == self.version {
            SoftDemoMessage::Tick(_) | SoftDemoMessage::Next => {
                self.queued_ticks = (self.queued_ticks + 1).min(self.speed);

                if let Some(task) = self.simulation.tick(self.queued_ticks) {
                    if let Some(speed) = self.next_speed.take() {
                        self.speed = speed;

                    self.queued_ticks = 0;

                    let version = self.version;

                    return Command::perform(task, move |message| {
                        SoftDemoMessage::Simulation(message, version)
    // This is where I need to be creating a custom subscription that the 
    // fn subscription() in the impl ProjectGui {} can subscribe to
    // pub fn subscription(&self) -> Subscription<SoftDemoMessage> {
    //    if self.is_playing {
    //        time::every(Duration::from_millis(1000 / self.speed as u64))
    //            .map(SoftDemoMessage::Tick)
    //    } else {
    //        Subscription::none()
    //    }
    // }
// If you need the Simulation and SimulationMessage, struct/enum, I can include
// If you need a fully functioning body of code then try to merge the two code bases below to achieve the same objective

Iced Gui Examples:
Tour (I need a gui with multiple pages)

Game_of_Life (I need a canvas running a simulation with a tick subscription on one page of pages: Vec)

Download_Progress (Best example I could find for creating a custom subscription but I cannot seem to wrap my head around how this is working)

you are calling map wrong, map expects a function which turns the inner type into another type. you probably are confused by the examples because they use enum variant as a function, but your variant Message::SoftDemo has different types. the correct syntax using a closure should be:

time::every(Duration::from_millis(1000 / self.soft_demo.speed as u64))
    .map(|instant| Message::SoftDemo(SoftDemoMessage::Tick(instant)))

alternatively, to use your SoftDemo::subscription(), you can do this:

impl Application for ProjectGui {
    // ... omitted other stuff
    fn subscription(&self) -> Subscription<Message> {

impl SoftDemo {
    fn subscription(&self) -> Subscription<SoftDemoMessage> {
        if self.is_playing {
            time::every(Duration::from_millis(1000 / self.speed as u64))
        } else {

explanation: think Subscription<T> as if it bahaves like Option<T>;

if you have a Subscription<A>:

let sub_a: Subscription<A> = todo!();

and you have a function takes a type A and returns a type B:

fn f(a: A) -> B {

then you can get a Subscription<B> by map-ping f over Subscription<A>:

let sub_b: Subscription<B> =;

btw, in mathematical term, Subscription is a functor.

in your example,

  • time::every(duration: Duration) returnes a Subscription<Instant>;
  • you map the enum variant SoftDemoMessage::Tick (which is also a constructor function that takes a Instant as argument and returns a SoftDemoMessage) over it and get a Subscription<SoftDemoMessage>;
  • you then map Message::SoftDemo over it to get the final Subscription<Message>
1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.