protoflow_blocks/
stdio.rs1extern crate std;
4
5use crate::{types::Encoding, ReadStdin, SysBlocks, System, WriteStderr, WriteStdout};
6use protoflow_core::prelude::{BTreeMap, FromStr, String, Vec};
7
8pub trait StdioSystem {
9 fn build_system(config: StdioConfig) -> Result<System, StdioError>;
10}
11
12#[derive(Debug, Default, Clone)]
13pub struct StdioConfig {
14 pub encoding: Encoding,
15 pub params: BTreeMap<String, String>,
16}
17
18impl StdioConfig {
19 pub fn reject_any(&self) -> Result<(), StdioError> {
20 if !self.params.is_empty() {
21 return Err(StdioError::UnknownParameter(
22 self.params.keys().next().unwrap().clone(),
23 ));
24 }
25 Ok(())
26 }
27
28 pub fn allow_only(&self, keys: Vec<&'static str>) -> Result<(), StdioError> {
29 for key in self.params.keys() {
30 if !keys.contains(&key.as_str()) {
31 return Err(StdioError::UnknownParameter(key.clone()));
32 }
33 }
34 Ok(())
35 }
36
37 pub fn get<T: FromStr>(&self, key: &'static str) -> Result<T, StdioError> {
38 self.get_string(key)?
39 .parse::<T>()
40 .map_err(|_| StdioError::InvalidParameter(key))
41 }
42
43 pub fn get_opt<T: FromStr>(&self, key: &'static str) -> Result<Option<T>, StdioError> {
44 match self.params.get(key) {
45 Some(value) => value
46 .parse::<T>()
47 .map_err(|_| StdioError::InvalidParameter(key))
48 .map(Some),
49 None => Ok(None),
50 }
51 }
52
53 pub fn get_string(&self, key: &'static str) -> Result<String, StdioError> {
54 let Some(value) = self.params.get(key).map(String::clone) else {
55 return Err(StdioError::MissingParameter(key))?;
56 };
57 Ok(value)
58 }
59
60 pub fn read_stdin(&self, system: &mut System) -> ReadStdin {
61 system.read_stdin() }
63
64 pub fn write_stdout(&self, system: &mut System) -> WriteStdout {
65 system.write_stdout() }
67
68 pub fn write_stderr(&self, system: &mut System) -> WriteStderr {
69 system.write_stderr() }
71}
72
73#[derive(Clone, Debug)]
74pub enum StdioError {
75 UnknownSystem(String),
76 UnknownParameter(String),
77 MissingParameter(&'static str),
78 InvalidParameter(&'static str),
79}
80
81impl std::error::Error for StdioError {}
82
83impl std::fmt::Display for StdioError {
84 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
85 use StdioError::*;
86 match self {
87 UnknownSystem(system) => {
88 write!(f, "unknown system: {}", system)
89 }
90 UnknownParameter(parameter) => {
91 write!(f, "unknown parameter: {}", parameter)
92 }
93 MissingParameter(parameter) => {
94 write!(f, "missing parameter: {}", parameter)
95 }
96 InvalidParameter(parameter) => {
97 write!(f, "invalid parameter: {}", parameter)
98 }
99 }
100 }
101}