context_weaver/core/processors/
rng.rs1use std::sync::Arc;
2
3use rand::Rng;
4
5use crate::{types::Number, WorldInfoNode, WorldInfoProcessor};
6
7use super::{PluginBridge, WorldInfoProcessorFactory};
8
9#[derive(Debug, Clone)]
10pub struct RngProcessor {
11 min: Number,
12 max: 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()..self.max.as_f64()).to_string())
36 } else {
37 let min = self.min.as_f64().round() as i64;
38 let max = self.max.as_f64().round() as i64;
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 let raw_min: crate::WorldInfoType = properties["min"].clone().into();
49 let raw_max: crate::WorldInfoType = properties["max"].clone().into();
50 let raw_decimal: crate::WorldInfoType = properties["decimal"].clone().into();
51
52 let min = match raw_min {
53 crate::WorldInfoType::Number(n) => n,
54 crate::WorldInfoType::String(s) => parse_number(&s).unwrap_or(Number::Int(0)),
55 _ => Number::Int(0),
56 };
57
58 let max = match raw_max {
59 crate::WorldInfoType::Number(n) => n,
60 crate::WorldInfoType::String(s) => parse_number(&s).unwrap_or(Number::Int(100)),
61 _ => Number::Int(100),
62 };
63
64 let decimals = match raw_decimal {
65 crate::WorldInfoType::Boolean(b) => b,
66 _ => false,
67 };
68
69 Box::new(RngProcessor { min, max, decimals })
70 }
71}
72
73fn parse_number(s: &str) -> Option<Number> {
74 if let Ok(i) = s.parse::<i64>() {
75 Some(Number::Int(i))
76 } else if let Ok(u) = s.parse::<u64>() {
77 Some(Number::UInt(u))
78 } else if let Ok(f) = s.parse::<f64>() {
79 Some(Number::Float(f))
80 } else {
81 None
82 }
83}