context_weaver/core/processors/
rng.rs1use 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}