context_weaver/core/processors/
rng.rs

1use std::sync::Arc;
2
3use rand::Rng;
4
5use crate::{WorldInfoNode, WorldInfoProcessor};
6
7use super::{PluginBridge, WorldInfoProcessorFactory};
8
9#[derive(Debug, Clone)]
10pub struct RngProcessor {
11    min: serde_json::Number,
12    max: serde_json::Number,
13    decimals: bool
14}
15
16impl WorldInfoNode for RngProcessor {
17    fn content(&self) -> Result<String, crate::WorldInfoError> {
18        self.process()
19    }
20
21    fn name(&self) -> String {
22        "weaver.core.rng".to_string()
23    }
24
25    fn cloned(&self) -> Box<dyn WorldInfoNode> {
26        Box::new(self.to_owned())
27    }
28}
29
30impl WorldInfoProcessor for RngProcessor {
31    fn process(&self) -> Result<String, crate::WorldInfoError> {
32        let mut rng = rand::rng();
33
34        if self.decimals {
35            Ok(rng.random_range(self.min.as_f64().unwrap()..self.max.as_f64().unwrap()).to_string())
36        } else {
37            let min = self.min.as_i64().unwrap();
38            let max = self.max.as_i64().unwrap();
39            Ok(rng.random_range(min..max).to_string())
40        }
41    }
42}
43
44pub struct RngProcessorFactory;
45
46impl<P: PluginBridge + 'static> WorldInfoProcessorFactory<P> for RngProcessorFactory {
47    fn create(&self, properties: &serde_json::Value, _bridge: &Arc<P>) -> Box<dyn WorldInfoProcessor> {
48        log::trace!("Creating rng processor");
49        let raw_min = properties["min"].clone();
50        let raw_max = properties["max"].clone();
51        let raw_decimal = properties["decimals"].clone();
52
53        let min = match raw_min {
54            serde_json::Value::Number(number) => number,
55            serde_json::Value::String(s) => parse_number(&s).unwrap(),
56            _ => 0.into()
57        };
58
59        let max = match raw_max {
60            serde_json::Value::Number(number) => number,
61            serde_json::Value::String(s) => parse_number(&s).unwrap(),
62            _ => 100.into()
63        };
64
65        let decimals = match raw_decimal {
66            serde_json::Value::Bool(b) => b,
67            _ => false
68        };
69
70        Box::new(RngProcessor { min, max, decimals })
71    }
72}
73
74fn parse_number(s: &str) -> Option<serde_json::Number> {
75    if let Ok(i) = s.parse::<i64>() {
76        Some(serde_json::Number::from(i))
77    } else if let Ok(u) = s.parse::<u64>() {
78        Some(serde_json::Number::from(u))
79    } else if let Ok(f) = s.parse::<f64>() {
80        Some(serde_json::Number::from_f64(f).unwrap())
81    } else {
82        None
83    }
84}