protoflow_blocks/blocks/sys/
read_env.rs1extern crate std;
4
5use crate::{
6 prelude::{vec, FromStr, String},
7 StdioConfig, StdioError, StdioSystem, System,
8};
9use protoflow_core::{Block, BlockResult, BlockRuntime, InputPort, Message, OutputPort};
10use protoflow_derive::Block;
11use simple_mermaid::mermaid;
12
13#[doc = mermaid!("../../../doc/sys/read_env.mmd")]
17#[doc = mermaid!("../../../doc/sys/read_env.seq.mmd" framed)]
20#[derive(Block, Clone)]
47pub struct ReadEnv<T: Message + FromStr = String> {
48 #[input]
50 pub name: InputPort<String>,
51
52 #[output]
54 pub output: OutputPort<T>,
55}
56
57impl<T: Message + FromStr> ReadEnv<T> {
58 pub fn new(name: InputPort<String>, output: OutputPort<T>) -> Self {
59 Self { name, output }
60 }
61}
62
63impl<T: Message + FromStr + 'static> ReadEnv<T> {
64 pub fn with_system(system: &System) -> Self {
65 use crate::SystemBuilding;
66 Self::new(system.input(), system.output())
67 }
68}
69
70impl<T: Message + FromStr> Block for ReadEnv<T> {
71 fn execute(&mut self, runtime: &dyn BlockRuntime) -> BlockResult {
72 runtime.wait_for(&self.name)?;
73 let name = self.name.recv()?.unwrap();
74 let value = std::env::var(&name).unwrap_or_default();
77 let value = T::from_str(&value).unwrap_or_default();
78 self.output.send(&value)?;
79
80 self.output.close()?;
81 Ok(())
82 }
83}
84
85#[cfg(feature = "std")]
86impl<T: Message + FromStr> StdioSystem for ReadEnv<T> {
87 fn build_system(config: StdioConfig) -> Result<System, StdioError> {
88 use crate::{CoreBlocks, IoBlocks, SysBlocks, SystemBuilding};
89
90 config.allow_only(vec!["name"])?;
91 let name = config.get_string("name")?;
92
93 Ok(System::build(|s| {
94 let name_param = s.const_string(name);
95 let env_reader = s.read_env();
96 let line_encoder = s.encode_with(config.encoding);
97 let stdout = config.write_stdout(s);
98 s.connect(&name_param.output, &env_reader.name);
99 s.connect(&env_reader.output, &line_encoder.input);
100 s.connect(&line_encoder.output, &stdout.input);
101 }))
102 }
103}
104
105#[cfg(test)]
106mod tests {
107 use super::ReadEnv;
108 use crate::{System, SystemBuilding};
109
110 #[test]
111 fn instantiate_block() {
112 let _ = System::build(|s| {
114 let _ = s.block(ReadEnv::<i32>::new(s.input(), s.output()));
115 });
116 }
117}