ComponentSender

Struct ComponentSender 

Source
pub struct ComponentSender<C: Component> { /* private fields */ }
Expand description

Contains senders to send and receive messages from a Component.

Implementations§

Source§

impl<C: Component> ComponentSender<C>

Source

pub fn input_sender(&self) -> &Sender<C::Input>

Retrieve the sender for input messages.

Useful to forward inputs from another component. If you just need to send input messages, input() is more concise.

Examples found in repository?
relm4/examples/worker.rs (line 97)
88    fn init(
89        _: Self::Init,
90        root: Self::Root,
91        sender: ComponentSender<Self>,
92    ) -> ComponentParts<Self> {
93        let model = App {
94            counter: 0,
95            worker: AsyncHandler::builder()
96                .detach_worker(())
97                .forward(sender.input_sender(), identity),
98        };
99
100        let widgets = view_output!();
101
102        ComponentParts { model, widgets }
103    }
More examples
Hide additional examples
relm4/examples/entry.rs (line 86)
77    fn init(
78        _init: Self::Init,
79        root: Self::Root,
80        sender: ComponentSender<Self>,
81    ) -> ComponentParts<Self> {
82        let factory_box = gtk::Box::default();
83
84        let counters = FactoryVecDeque::builder()
85            .launch(factory_box.clone())
86            .forward(sender.input_sender(), |output| output);
87
88        let model = App {
89            counters,
90            created_counters: 0,
91            entry: gtk::EntryBuffer::default(),
92        };
93
94        let widgets = view_output!();
95
96        ComponentParts { model, widgets }
97    }
relm4/examples/to_do.rs (line 148)
140    fn init(
141        _: Self::Init,
142        root: Self::Root,
143        sender: ComponentSender<Self>,
144    ) -> ComponentParts<Self> {
145        let tasks =
146            FactoryVecDeque::builder()
147                .launch_default()
148                .forward(sender.input_sender(), |output| match output {
149                    TaskOutput::Delete(index) => AppMsg::DeleteEntry(index),
150                });
151
152        let model = App { tasks };
153
154        let task_list_box = model.tasks.widget();
155        let widgets = view_output!();
156
157        ComponentParts { model, widgets }
158    }
relm4-components/examples/adw_combo_row.rs (line 73)
62    fn init(
63        _: Self::Init,
64        root: Self::Root,
65        sender: ComponentSender<Self>,
66    ) -> ComponentParts<Self> {
67        let model = App {
68            combo_row: SimpleComboRow::builder()
69                .launch(SimpleComboRow {
70                    variants: vec!["Variant 1", "Variant 2"],
71                    active_index: None,
72                })
73                .forward(sender.input_sender(), AppMsg::Selected),
74            selected_variant: 0,
75        };
76
77        let combo_row = model.combo_row.widget();
78        let widgets = view_output!();
79
80        ComponentParts { model, widgets }
81    }
relm4/examples/message_broker.rs (line 193)
186    fn init(
187        _init: Self::Init,
188        root: Self::Root,
189        sender: ComponentSender<Self>,
190    ) -> ComponentParts<Self> {
191        let header = Header::builder()
192            .launch_with_broker((), &HEADER_BROKER)
193            .forward(sender.input_sender(), identity);
194
195        let dialog = Dialog::builder()
196            .launch(root.clone().upcast())
197            .forward(sender.input_sender(), identity);
198
199        let model = App {
200            mode: AppMode::View,
201            header,
202            dialog,
203        };
204
205        let widgets = view_output!();
206
207        ComponentParts { model, widgets }
208    }
relm4-components/examples/open_button.rs (line 58)
45    fn init(
46        _: Self::Init,
47        root: Self::Root,
48        sender: ComponentSender<Self>,
49    ) -> ComponentParts<Self> {
50        let open_button = OpenButton::builder()
51            .launch(OpenButtonSettings {
52                dialog_settings: OpenDialogSettings::default(),
53                icon: None,
54                text: "Open file",
55                recently_opened_files: Some(".recent_files"),
56                max_recent_files: 10,
57            })
58            .forward(sender.input_sender(), AppMsg::Open);
59        let model = App { open_button };
60
61        let widgets = view_output!();
62
63        ComponentParts { model, widgets }
64    }
Source

pub fn output_sender(&self) -> &Sender<C::Output>

Retrieve the sender for output messages.

Useful to forward outputs from another component. If you just need to send output messages, output() is more concise.

Source

pub fn command_sender(&self) -> &Sender<C::CommandOutput>

Retrieve the sender for command output messages.

Useful to forward outputs from another component. If you just need to send output messages, command() is more concise.

Source

pub fn input(&self, message: C::Input)

Emit an input to the component.

Examples found in repository?
relm4/examples/message_from_grid_view.rs (line 85)
77    fn bind(&mut self, widgets: &mut Self::Widgets, _root: &mut Self::Root) {
78        widgets.label.set_label(self.name);
79        let name = self.name;
80        let button_click_handler_id = widgets.button.connect_clicked(glib::clone!(
81            #[strong(rename_to = sender)]
82            self.sender,
83            move |_btn| {
84                // Use the cloned sender to send a message
85                sender.input(Msg::Print(name));
86            }
87        ));
88        self.button_click_handler_id
89            .replace(button_click_handler_id);
90    }
More examples
Hide additional examples
relm4/examples/toast.rs (line 98)
87    fn update(&mut self, msg: Self::Input, sender: ComponentSender<Self>) {
88        match msg {
89            Msg::Activate => {
90                self.activated = "Active";
91                let toast = adw::Toast::builder()
92                    .title("Activated")
93                    .button_label("Cancel")
94                    .timeout(0)
95                    .build();
96                toast.connect_button_clicked(move |this| {
97                    this.dismiss();
98                    sender.input(Msg::Cancel);
99                });
100                self.toaster.add_toast(toast);
101            }
102            Msg::Cancel => self.activated = "Idle",
103        }
104    }
relm4/examples/tab_game.rs (line 280)
273    fn update_cmd(
274        &mut self,
275        msg: Self::CommandOutput,
276        sender: ComponentSender<Self>,
277        _root: &Self::Root,
278    ) {
279        if msg {
280            sender.input(AppMsg::StopGame);
281        } else {
282            let mut counters_guard = self.counters.guard();
283            match rand::random::<u8>() % 3 {
284                0 => {
285                    counters_guard.swap(1, 2);
286                }
287                1 => {
288                    counters_guard.swap(0, 1);
289                }
290                _ => {
291                    let widget = counters_guard.widget();
292                    if !widget.select_next_page() {
293                        widget.select_previous_page();
294                    }
295                }
296            }
297        }
298    }
relm4/examples/actions.rs (line 72)
55    fn init(
56        _init: Self::Init,
57        root: Self::Root,
58        sender: ComponentSender<Self>,
59    ) -> ComponentParts<Self> {
60        let menu_model = gtk::gio::Menu::new();
61        menu_model.append(Some("Stateless"), Some(&ExampleAction::action_name()));
62
63        let model = Self { counter: 0 };
64
65        let widgets = view_output!();
66
67        let app = relm4::main_application();
68        app.set_accelerators_for_action::<ExampleAction>(&["<primary>W"]);
69
70        let action: RelmAction<ExampleAction> = RelmAction::new_stateless(move |_| {
71            println!("Statelesss action!");
72            sender.input(Msg::Increment);
73        });
74
75        let action2: RelmAction<ExampleU8Action> =
76            RelmAction::new_stateful_with_target_value(&0, |_, state, value| {
77                println!("Stateful action -> state: {state}, value: {value}");
78                *state += value;
79            });
80
81        let mut group = RelmActionGroup::<WindowActionGroup>::new();
82        group.add_action(action);
83        group.add_action(action2);
84        group.register_for_widget(&widgets.main_window);
85
86        ComponentParts { model, widgets }
87    }
relm4/examples/simple_manual.rs (line 67)
39    fn init(
40        counter: Self::Init,
41        window: Self::Root,
42        sender: ComponentSender<Self>,
43    ) -> ComponentParts<Self> {
44        let model = AppModel { counter };
45
46        let vbox = gtk::Box::builder()
47            .orientation(gtk::Orientation::Vertical)
48            .spacing(5)
49            .build();
50
51        let inc_button = gtk::Button::with_label("Increment");
52        let dec_button = gtk::Button::with_label("Decrement");
53
54        let label = gtk::Label::new(Some(&format!("Counter: {}", model.counter)));
55        label.set_margin_all(5);
56
57        window.set_child(Some(&vbox));
58        vbox.set_margin_all(5);
59        vbox.append(&inc_button);
60        vbox.append(&dec_button);
61        vbox.append(&label);
62
63        inc_button.connect_clicked(clone!(
64            #[strong]
65            sender,
66            move |_| {
67                sender.input(AppMsg::Increment);
68            }
69        ));
70
71        dec_button.connect_clicked(clone!(
72            #[strong]
73            sender,
74            move |_| {
75                sender.input(AppMsg::Decrement);
76            }
77        ));
78
79        let widgets = AppWidgets { label };
80
81        ComponentParts { model, widgets }
82    }
relm4-components/examples/file_dialogs.rs (lines 124-126)
93    fn init(
94        _: Self::Init,
95        root: Self::Root,
96        sender: ComponentSender<Self>,
97    ) -> ComponentParts<Self> {
98        let open_dialog = OpenDialog::builder()
99            .transient_for_native(&root)
100            .launch(OpenDialogSettings::default())
101            .forward(sender.input_sender(), |response| match response {
102                OpenDialogResponse::Accept(path) => Input::OpenResponse(path),
103                OpenDialogResponse::Cancel => Input::Ignore,
104            });
105
106        let save_dialog = SaveDialog::builder()
107            .transient_for_native(&root)
108            .launch(SaveDialogSettings::default())
109            .forward(sender.input_sender(), |response| match response {
110                SaveDialogResponse::Accept(path) => Input::SaveResponse(path),
111                SaveDialogResponse::Cancel => Input::Ignore,
112            });
113
114        let model = App {
115            open_dialog,
116            save_dialog,
117            buffer: gtk::TextBuffer::new(None),
118            file_name: None,
119            message: None,
120        };
121
122        let widgets = view_output!();
123
124        sender.input(Input::ShowMessage(String::from(
125            "A simple text editor showing the usage of\n<b>OpenFileDialog</b> and <b>SaveFileDialog</b> components.\n\nStart by clicking <b>Open</b> on the header bar.",
126        )));
127
128        ComponentParts { model, widgets }
129    }
130
131    fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
132        match message {
133            Input::OpenRequest => self.open_dialog.emit(OpenDialogMsg::Open),
134            Input::OpenResponse(path) => match std::fs::read_to_string(&path) {
135                Ok(contents) => {
136                    self.buffer.set_text(&contents);
137                    self.file_name = Some(
138                        path.file_name()
139                            .expect("The path has no file name")
140                            .to_str()
141                            .expect("Cannot convert file name to string")
142                            .to_string(),
143                    );
144                }
145                Err(e) => sender.input(Input::ShowMessage(e.to_string())),
146            },
147            Input::SaveRequest => self
148                .save_dialog
149                .emit(SaveDialogMsg::SaveAs(self.file_name.clone().unwrap())),
150            Input::SaveResponse(path) => match std::fs::write(
151                &path,
152                self.buffer
153                    .text(&self.buffer.start_iter(), &self.buffer.end_iter(), false),
154            ) {
155                Ok(_) => {
156                    sender.input(Input::ShowMessage(format!(
157                        "File saved successfully at {path:?}"
158                    )));
159                    self.buffer.set_text("");
160                    self.file_name = None;
161                }
162                Err(e) => sender.input(Input::ShowMessage(e.to_string())),
163            },
164            Input::ShowMessage(message) => {
165                self.message = Some(message);
166            }
167            Input::ResetMessage => {
168                self.message = None;
169            }
170            Input::Ignore => {}
171        }
172    }
Source

pub fn output(&self, message: C::Output) -> Result<(), C::Output>

Emit an output to the component.

Returns Err if all receivers were dropped, for example by detach.

Examples found in repository?
relm4/examples/message_stream.rs (line 66)
63    fn update(&mut self, msg: Self::Input, sender: ComponentSender<Self>) {
64        match msg {
65            DialogMsg::Accept => {
66                sender.output(self.buffer.text().into()).unwrap();
67            }
68            DialogMsg::Cancel => {
69                sender.output(String::default()).unwrap();
70            }
71        }
72    }
More examples
Hide additional examples
relm4/examples/worker.rs (line 46)
42    fn update(&mut self, msg: AsyncHandlerMsg, sender: ComponentSender<Self>) {
43        std::thread::sleep(Duration::from_secs(1));
44
45        match msg {
46            AsyncHandlerMsg::DelayedIncrement => sender.output(AppMsg::Increment).unwrap(),
47            AsyncHandlerMsg::DelayedDecrement => sender.output(AppMsg::Decrement).unwrap(),
48        }
49    }
relm4/examples/components.rs (line 127)
122    fn update(&mut self, msg: Self::Input, sender: ComponentSender<Self>) {
123        match msg {
124            DialogMsg::Show => self.hidden = false,
125            DialogMsg::Accept => {
126                self.hidden = true;
127                sender.output(AppMsg::Close).unwrap();
128            }
129            DialogMsg::Cancel => self.hidden = true,
130        }
131    }
relm4/examples/settings_list.rs (line 132)
126    fn init(
127        title: Self::Init,
128        root: Self::Root,
129        sender: ComponentSender<Self>,
130    ) -> ComponentParts<Self> {
131        // Request the caller to reload its options.
132        sender.output(Output::Reload).unwrap();
133
134        let label = gtk::Label::builder().label(title).margin_top(24).build();
135
136        let list = gtk::ListBox::builder()
137            .halign(gtk::Align::Center)
138            .margin_bottom(24)
139            .margin_top(24)
140            .selection_mode(gtk::SelectionMode::None)
141            .build();
142
143        root.append(&label);
144        root.append(&list);
145
146        ComponentParts {
147            model: AppModel::default(),
148            widgets: Widgets {
149                list,
150                button_sg: gtk::SizeGroup::new(gtk::SizeGroupMode::Both),
151                options: Default::default(),
152            },
153        }
154    }
155
156    fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>, _root: &Self::Root) {
157        match message {
158            Input::AddSetting {
159                description,
160                button,
161                id,
162            } => {
163                self.options.push((description, button, id));
164            }
165
166            Input::Clear => {
167                self.options.clear();
168
169                // Perform this async operation.
170                sender.oneshot_command(async move {
171                    tokio::time::sleep(std::time::Duration::from_secs(2)).await;
172                    CmdOut::Reload
173                });
174            }
175
176            Input::Reload => {
177                sender.output(Output::Reload).unwrap();
178            }
179        }
180    }
181
182    fn update_cmd(
183        &mut self,
184        message: Self::CommandOutput,
185        sender: ComponentSender<Self>,
186        _root: &Self::Root,
187    ) {
188        match message {
189            CmdOut::Reload => {
190                sender.output(Output::Reload).unwrap();
191            }
192        }
193    }
194
195    fn update_view(&self, widgets: &mut Self::Widgets, sender: ComponentSender<Self>) {
196        if self.options.is_empty() && !widgets.options.is_empty() {
197            widgets.list.remove_all();
198        } else if self.options.len() != widgets.options.len()
199            && let Some((description, button_label, id)) = self.options.last()
200        {
201            let id = *id;
202            relm4::view! {
203                widget = gtk::Box {
204                    set_orientation: gtk::Orientation::Horizontal,
205                    set_margin_start: 20,
206                    set_margin_end: 20,
207                    set_margin_top: 8,
208                    set_margin_bottom: 8,
209                    set_spacing: 24,
210
211                    append = &gtk::Label {
212                        set_label: description,
213                        set_halign: gtk::Align::Start,
214                        set_hexpand: true,
215                        set_valign: gtk::Align::Center,
216                        set_ellipsize: gtk::pango::EllipsizeMode::End,
217                    },
218
219                    append: button = &gtk::Button {
220                        set_label: button_label,
221                        set_size_group: &widgets.button_sg,
222
223                        connect_clicked[sender] => move |_| {
224                            sender.output(Output::Clicked(id)).unwrap();
225                        }
226                    }
227                }
228            }
229
230            widgets.list.append(&widget);
231            widgets.options.push(widget);
232        }
233    }
relm4/examples/state_management.rs (line 309)
289    fn update(&mut self, input: DocumentInput, sender: ComponentSender<Self>) {
290        match input {
291            DocumentInput::Save(path) => {
292                println!("Save as JSON to {path:?}");
293
294                // TODO in a real app you would report any errors from saving the document
295                if let Ok(json) = serde_json::to_string(&self.model) {
296                    std::fs::write(path, json).unwrap();
297                }
298            }
299            DocumentInput::Open(path) => {
300                println!("Open tasks document at {path:?}");
301
302                if let Ok(json) = std::fs::read_to_string(path)
303                    && let Ok(new_model) = serde_json::from_str(&json)
304                {
305                    // update the data model
306                    self.model = new_model;
307
308                    // refresh the view from the data model
309                    let _ = sender.output(DocumentOutput::Cleared);
310
311                    for (task_index, task) in self.model.tasks.iter().enumerate() {
312                        let _ = sender.output(DocumentOutput::AddedTask);
313
314                        let task_name = task.name.clone();
315                        let _ =
316                            sender.output(DocumentOutput::ChangedTaskName(task_index, task_name));
317
318                        for tag in &task.tags {
319                            let tag_name = tag.name.clone();
320                            let _ = sender.output(DocumentOutput::AddedTag(task_index, tag_name));
321                        }
322                    }
323                }
324            }
325            DocumentInput::Clear => {
326                self.model.tasks.clear();
327
328                let _ = sender.output(DocumentOutput::Cleared);
329            }
330            DocumentInput::AddTask => {
331                self.model.tasks.push(TaskModel::default());
332
333                let _ = sender.output(DocumentOutput::AddedTask);
334            }
335            DocumentInput::DeleteTask(index) => {
336                self.model.tasks.remove(index.current_index());
337
338                let _ = sender.output(DocumentOutput::DeletedTask(index.current_index()));
339            }
340            DocumentInput::ChangeTaskName(index, name) => {
341                if let Some(task) = self.model.tasks.get_mut(index.current_index()) {
342                    task.name.clone_from(&name);
343                }
344
345                // We don't technically need to send an event, because gtk::Entry updates itself
346                // this is just to make the example consistent.
347                let _ = sender.output(DocumentOutput::ChangedTaskName(index.current_index(), name));
348            }
349            DocumentInput::AddTag(task_index, name) => {
350                if let Some(task) = self.model.tasks.get_mut(task_index.current_index()) {
351                    task.tags.push(TagModel { name: name.clone() })
352                }
353
354                let _ = sender.output(DocumentOutput::AddedTag(task_index.current_index(), name));
355            }
356            DocumentInput::DeleteTag(task_index, tag_index) => {
357                if let Some(task) = self.model.tasks.get_mut(task_index.current_index()) {
358                    task.tags.remove(tag_index.current_index());
359                }
360
361                let _ = sender.output(DocumentOutput::DeletedTag(
362                    task_index.current_index(),
363                    tag_index.current_index(),
364                ));
365            }
366        }
367    }
Source

pub fn command<Cmd, Fut>(&self, cmd: Cmd)
where Cmd: FnOnce(Sender<C::CommandOutput>, ShutdownReceiver) -> Fut + Send + 'static, Fut: Future<Output = ()> + Send,

Spawns an asynchronous command. You can bind the the command to the lifetime of the component by using a ShutdownReceiver.

Examples found in repository?
relm4/examples/drawing.rs (lines 129-138)
114    fn init(
115        _: Self::Init,
116        root: Self::Root,
117        sender: ComponentSender<Self>,
118    ) -> ComponentParts<Self> {
119        let model = App {
120            width: 100.0,
121            height: 100.0,
122            points: Vec::new(),
123            handler: DrawHandler::new(),
124        };
125
126        let area = model.handler.drawing_area();
127        let widgets = view_output!();
128
129        sender.command(|out, shutdown| {
130            shutdown
131                .register(async move {
132                    loop {
133                        tokio::time::sleep(Duration::from_millis(20)).await;
134                        out.send(UpdatePointsMsg).unwrap();
135                    }
136                })
137                .drop_on_shutdown()
138        });
139
140        ComponentParts { model, widgets }
141    }
More examples
Hide additional examples
relm4/examples/progress.rs (lines 124-142)
120    fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>, _root: &Self::Root) {
121        match message {
122            Input::Compute => {
123                self.computing = true;
124                sender.command(|out, shutdown| {
125                    shutdown
126                        // Performs this operation until a shutdown is triggered
127                        .register(async move {
128                            let mut progress = 0.0;
129
130                            while progress < 1.0 {
131                                out.send(CmdOut::Progress(progress)).unwrap();
132                                progress += 0.1;
133                                tokio::time::sleep(std::time::Duration::from_millis(333)).await;
134                            }
135
136                            out.send(CmdOut::Finished(Ok("42".into()))).unwrap();
137                        })
138                        // Perform task until a shutdown interrupts it
139                        .drop_on_shutdown()
140                        // Wrap into a `Pin<Box<Future>>` for return
141                        .boxed()
142                });
143            }
144        }
145    }
relm4/examples/tab_game.rs (lines 250-262)
246    fn update(&mut self, msg: Self::Input, sender: ComponentSender<Self>, _root: &Self::Root) {
247        match msg {
248            AppMsg::StartGame(index) => {
249                self.start_index = Some(index);
250                sender.command(|sender, _| async move {
251                    for i in (1..4).rev() {
252                        *GAME_STATE.write() = GameState::Countdown(i);
253                        relm4::tokio::time::sleep(Duration::from_millis(1000)).await;
254                    }
255                    *GAME_STATE.write() = GameState::Running;
256                    for _ in 0..20 {
257                        relm4::tokio::time::sleep(Duration::from_millis(500)).await;
258                        sender.send(false).unwrap();
259                    }
260                    relm4::tokio::time::sleep(Duration::from_millis(1000)).await;
261                    sender.send(true).unwrap();
262                });
263            }
264            AppMsg::StopGame => {
265                *GAME_STATE.write() = GameState::Guessing;
266            }
267            AppMsg::SelectedGuess(index) => {
268                *GAME_STATE.write() = GameState::End(index == self.start_index.take().unwrap());
269            }
270        }
271    }
Source

pub fn spawn_command<Cmd>(&self, cmd: Cmd)
where Cmd: FnOnce(Sender<C::CommandOutput>) + Send + 'static,

Spawns a synchronous command.

This is particularly useful for CPU-intensive background jobs that need to run on a thread-pool in the background.

If you expect the component to be dropped while the command is running take care while sending messages!

Source

pub fn oneshot_command<Fut>(&self, future: Fut)
where Fut: Future<Output = C::CommandOutput> + Send + 'static,

Spawns a future that will be dropped as soon as the factory component is shut down.

Essentially, this is a simpler version of Self::command().

Examples found in repository?
relm4/examples/settings_list.rs (lines 170-173)
156    fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>, _root: &Self::Root) {
157        match message {
158            Input::AddSetting {
159                description,
160                button,
161                id,
162            } => {
163                self.options.push((description, button, id));
164            }
165
166            Input::Clear => {
167                self.options.clear();
168
169                // Perform this async operation.
170                sender.oneshot_command(async move {
171                    tokio::time::sleep(std::time::Duration::from_secs(2)).await;
172                    CmdOut::Reload
173                });
174            }
175
176            Input::Reload => {
177                sender.output(Output::Reload).unwrap();
178            }
179        }
180    }
More examples
Hide additional examples
relm4/examples/message_stream.rs (lines 150-172)
141    fn update(&mut self, msg: Self::Input, sender: ComponentSender<Self>, root: &Self::Root) {
142        match msg {
143            AppMsg::StartSearch => {
144                self.searching = true;
145
146                let stream = Dialog::builder()
147                    .transient_for(root)
148                    .launch(())
149                    .into_stream();
150                sender.oneshot_command(async move {
151                    // Use the component as stream
152                    let result = stream.recv_one().await;
153
154                    if let Some(search) = result {
155                        let response =
156                            reqwest::get(format!("https://duckduckgo.com/lite/?q={search}"))
157                                .await
158                                .unwrap();
159                        let response_text = response.text().await.unwrap();
160
161                        // Extract the url of the first search result.
162                        if let Some(url) = response_text.split("<a rel=\"nofollow\" href=\"").nth(1)
163                        {
164                            let url = url.split('\"').next().unwrap().replace("amp;", "");
165                            Some(format!("https:{url}"))
166                        } else {
167                            None
168                        }
169                    } else {
170                        None
171                    }
172                });
173            }
174        }
175    }
Source

pub fn spawn_oneshot_command<Cmd>(&self, cmd: Cmd)
where Cmd: FnOnce() -> C::CommandOutput + Send + 'static,

Spawns a synchronous command that will be dropped as soon as the factory component is shut down.

Essentially, this is a simpler version of Self::spawn_command().

Trait Implementations§

Source§

impl<C: Component> Clone for ComponentSender<C>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<C: Debug + Component> Debug for ComponentSender<C>
where C::Input: Debug, C::Output: Debug, C::CommandOutput: Debug,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<C> Freeze for ComponentSender<C>

§

impl<C> RefUnwindSafe for ComponentSender<C>

§

impl<C> Send for ComponentSender<C>
where <C as Component>::Input: Send, <C as Component>::Output: Send,

§

impl<C> Sync for ComponentSender<C>
where <C as Component>::Input: Send, <C as Component>::Output: Send,

§

impl<C> Unpin for ComponentSender<C>

§

impl<C> UnwindSafe for ComponentSender<C>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<C> AsyncPosition<()> for C

Source§

fn position(_index: usize)

Returns the position. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<C, I> Position<(), I> for C

Source§

fn position(&self, _index: &I)

Returns the position. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more