Skip to main content

ranvier_std/nodes/
string.rs

1use async_trait::async_trait;
2use ranvier_core::{bus::Bus, outcome::Outcome, transition::Transition};
3use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5use std::fmt::Debug;
6
7#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
8pub enum StringOperation {
9    Append(String),
10    Prepend(String),
11    ToUpper,
12    ToLower,
13}
14
15#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
16pub struct StringNode {
17    pub operation: StringOperation,
18}
19
20impl StringNode {
21    pub fn new(operation: StringOperation) -> Self {
22        Self { operation }
23    }
24}
25
26#[async_trait]
27impl Transition<String, String> for StringNode {
28    type Error = String;
29    type Resources = ();
30
31    async fn run(
32        &self,
33        input: String,
34        _resources: &Self::Resources,
35        _bus: &mut Bus,
36    ) -> Outcome<String, Self::Error> {
37        match &self.operation {
38            StringOperation::Append(s) => Outcome::next(format!("{}{}", input, s)),
39            StringOperation::Prepend(s) => Outcome::next(format!("{}{}", s, input)),
40            StringOperation::ToUpper => Outcome::next(input.to_uppercase()),
41            StringOperation::ToLower => Outcome::next(input.to_lowercase()),
42        }
43    }
44}
45
46#[cfg(test)]
47mod tests {
48    use super::*;
49
50    #[tokio::test]
51    async fn string_append() {
52        let node = StringNode::new(StringOperation::Append(" world".into()));
53        let mut bus = Bus::new();
54        let result = node.run("hello".into(), &(), &mut bus).await;
55        assert!(matches!(result, Outcome::Next(ref v) if v == "hello world"));
56    }
57
58    #[tokio::test]
59    async fn string_prepend() {
60        let node = StringNode::new(StringOperation::Prepend("prefix_".into()));
61        let mut bus = Bus::new();
62        let result = node.run("data".into(), &(), &mut bus).await;
63        assert!(matches!(result, Outcome::Next(ref v) if v == "prefix_data"));
64    }
65
66    #[tokio::test]
67    async fn string_to_upper() {
68        let node = StringNode::new(StringOperation::ToUpper);
69        let mut bus = Bus::new();
70        let result = node.run("hello".into(), &(), &mut bus).await;
71        assert!(matches!(result, Outcome::Next(ref v) if v == "HELLO"));
72    }
73
74    #[tokio::test]
75    async fn string_to_lower() {
76        let node = StringNode::new(StringOperation::ToLower);
77        let mut bus = Bus::new();
78        let result = node.run("HELLO".into(), &(), &mut bus).await;
79        assert!(matches!(result, Outcome::Next(ref v) if v == "hello"));
80    }
81}