system_piping/
system_piping.rs

1//! Illustrates how to make a single system from multiple functions running in sequence,
2//! passing the output of the first into the input of the next.
3
4use bevy::prelude::*;
5use std::num::ParseIntError;
6
7use bevy::log::{debug, error, info, Level, LogPlugin};
8
9fn main() {
10    App::new()
11        .insert_resource(Message("42".to_string()))
12        .insert_resource(OptionalWarning(Err("Got to rusty?".to_string())))
13        .add_plugins(LogPlugin {
14            level: Level::TRACE,
15            filter: "".to_string(),
16            ..default()
17        })
18        .add_systems(
19            Update,
20            (
21                parse_message_system.pipe(handler_system),
22                data_pipe_system.map(|out| info!("{out}")),
23                parse_message_system.map(|out| debug!("{out:?}")),
24                warning_pipe_system.map(|out| {
25                    if let Err(err) = out {
26                        error!("{err}");
27                    }
28                }),
29                parse_error_message_system.map(|out| {
30                    if let Err(err) = out {
31                        error!("{err}");
32                    }
33                }),
34                parse_message_system.map(drop),
35            ),
36        )
37        .run();
38}
39
40#[derive(Resource, Deref)]
41struct Message(String);
42
43#[derive(Resource, Deref)]
44struct OptionalWarning(Result<(), String>);
45
46// This system produces a Result<usize> output by trying to parse the Message resource.
47fn parse_message_system(message: Res<Message>) -> Result<usize, ParseIntError> {
48    message.parse::<usize>()
49}
50
51// This system produces a Result<()> output by trying to parse the Message resource.
52fn parse_error_message_system(message: Res<Message>) -> Result<(), ParseIntError> {
53    message.parse::<usize>()?;
54    Ok(())
55}
56
57// This system takes a Result<usize> input and either prints the parsed value or the error message
58// Try changing the Message resource to something that isn't an integer. You should see the error
59// message printed.
60fn handler_system(In(result): In<Result<usize, ParseIntError>>) {
61    match result {
62        Ok(value) => println!("parsed message: {value}"),
63        Err(err) => println!("encountered an error: {err:?}"),
64    }
65}
66
67// This system produces a String output by trying to clone the String from the Message resource.
68fn data_pipe_system(message: Res<Message>) -> String {
69    message.0.clone()
70}
71
72// This system produces a Result<String> output by trying to extract a String from the
73// OptionalWarning resource. Try changing the OptionalWarning resource to None. You should
74// not see the warning message printed.
75fn warning_pipe_system(message: Res<OptionalWarning>) -> Result<(), String> {
76    message.0.clone()
77}