Skip to content

Commit 8abe840

Browse files
committed
feat: added to_value function to turn strings, numbers, booleans & lists
into a value
1 parent 6a8952d commit 8abe840

File tree

3 files changed

+205
-4
lines changed

3 files changed

+205
-4
lines changed

build/rust/src/shared/helper/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
pub mod path;
2+
pub mod rule;
23
pub mod value;

build/rust/src/shared/helper/path.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::shared::{value::Kind, ListValue, Struct, Value};
1+
use crate::shared::{ListValue, Struct, Value, value::Kind};
22
use std::collections::HashMap;
33

44
/// Get the Kind at a given path from a Value
@@ -181,11 +181,11 @@ pub fn set_value(path: &str, current: &Value, new_value: Value) -> Value {
181181
pub mod tests {
182182

183183
use crate::shared::{
184+
Struct, Value,
184185
helper::path::{
185186
exists_path, expect_kind, get_bool, get_list, get_number, get_string, get_struct,
186187
set_value,
187188
},
188-
Struct, Value,
189189
};
190190
use std::collections::HashMap;
191191

build/rust/src/shared/helper/value.rs

Lines changed: 202 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,81 @@
1-
use crate::shared::value::Kind;
2-
use crate::shared::{ListValue, Struct, Value};
1+
use crate::shared::{ListValue, Struct, Value, value::Kind};
32
use serde_json::{Number, Value as JsonValue};
3+
use std::collections::HashMap;
4+
5+
pub trait ToValue {
6+
fn to_value(&self) -> Value;
7+
}
8+
9+
impl ToValue for &str {
10+
fn to_value(&self) -> Value {
11+
Value {
12+
kind: Some(Kind::StringValue(self.to_string())),
13+
}
14+
}
15+
}
16+
17+
impl ToValue for String {
18+
fn to_value(&self) -> Value {
19+
Value {
20+
kind: Some(Kind::StringValue(self.to_owned())),
21+
}
22+
}
23+
}
24+
25+
impl ToValue for bool {
26+
fn to_value(&self) -> Value {
27+
Value {
28+
kind: Some(Kind::BoolValue(self.to_owned())),
29+
}
30+
}
31+
}
32+
33+
impl ToValue for i64 {
34+
fn to_value(&self) -> Value {
35+
Value {
36+
kind: Some(Kind::NumberValue(self.to_owned() as f64)),
37+
}
38+
}
39+
}
40+
41+
impl ToValue for f64 {
42+
fn to_value(&self) -> Value {
43+
Value {
44+
kind: Some(Kind::NumberValue(self.to_owned())),
45+
}
46+
}
47+
}
48+
49+
impl<T: ToValue> ToValue for Vec<T> {
50+
fn to_value(&self) -> Value {
51+
let values = self.iter().map(|item| item.to_value()).collect();
52+
Value {
53+
kind: Some(Kind::ListValue(ListValue { values })),
54+
}
55+
}
56+
}
57+
58+
impl<T: ToValue> ToValue for Option<T> {
59+
fn to_value(&self) -> Value {
60+
match self {
61+
Some(val) => val.to_value(),
62+
None => Value { kind: None }, // or Some(Kind::NullValue(...)) if supported
63+
}
64+
}
65+
}
66+
67+
impl<T: ToValue> ToValue for HashMap<String, T> {
68+
fn to_value(&self) -> Value {
69+
let fields = self
70+
.iter()
71+
.map(|(k, v)| (k.clone(), v.to_value()))
72+
.collect();
73+
74+
Value {
75+
kind: Some(Kind::StructValue(Struct { fields })),
76+
}
77+
}
78+
}
479

580
/// Converts a serde_json::Value into our internal Value type
681
pub fn from_json_value(value: JsonValue) -> Value {
@@ -269,4 +344,129 @@ mod tests {
269344
let json_val = to_json_value(val);
270345
assert!(json_val.is_null());
271346
}
347+
348+
use crate::shared::{ListValue, Struct, Value, value::Kind};
349+
use std::collections::HashMap;
350+
351+
#[test]
352+
fn test_string_to_value() {
353+
let s = "hello".to_value();
354+
assert_eq!(
355+
s,
356+
Value {
357+
kind: Some(Kind::StringValue("hello".to_string()))
358+
}
359+
);
360+
}
361+
362+
#[test]
363+
fn test_string_owned_to_value() {
364+
let s = String::from("world").to_value();
365+
assert_eq!(
366+
s,
367+
Value {
368+
kind: Some(Kind::StringValue("world".to_string()))
369+
}
370+
);
371+
}
372+
373+
#[test]
374+
fn test_bool_to_value() {
375+
assert_eq!(
376+
true.to_value(),
377+
Value {
378+
kind: Some(Kind::BoolValue(true))
379+
}
380+
);
381+
}
382+
383+
#[test]
384+
fn test_i64_to_value() {
385+
assert_eq!(
386+
(42i64).to_value(),
387+
Value {
388+
kind: Some(Kind::NumberValue(42.0))
389+
}
390+
);
391+
}
392+
393+
#[test]
394+
fn test_f64_to_value() {
395+
assert_eq!(
396+
(3.14f64).to_value(),
397+
Value {
398+
kind: Some(Kind::NumberValue(3.14))
399+
}
400+
);
401+
}
402+
403+
#[test]
404+
fn test_vec_to_value() {
405+
let v = vec![1i64, 2i64, 3i64];
406+
let expected = Value {
407+
kind: Some(Kind::ListValue(ListValue {
408+
values: vec![
409+
Value {
410+
kind: Some(Kind::NumberValue(1.0)),
411+
},
412+
Value {
413+
kind: Some(Kind::NumberValue(2.0)),
414+
},
415+
Value {
416+
kind: Some(Kind::NumberValue(3.0)),
417+
},
418+
],
419+
})),
420+
};
421+
assert_eq!(v.to_value(), expected);
422+
}
423+
424+
#[test]
425+
fn test_option_some_to_value() {
426+
let opt = Some(10i64);
427+
assert_eq!(
428+
opt.to_value(),
429+
Value {
430+
kind: Some(Kind::NumberValue(10.0))
431+
}
432+
);
433+
}
434+
435+
#[test]
436+
fn test_option_none_to_value() {
437+
let opt: Option<i64> = None;
438+
assert_eq!(opt.to_value(), Value { kind: None });
439+
}
440+
441+
#[test]
442+
fn test_hashmap_to_value() {
443+
let mut map = HashMap::new();
444+
map.insert("a".to_string(), 1i64);
445+
map.insert("b".to_string(), 2i64);
446+
447+
let expected_fields = {
448+
let mut fields = HashMap::new();
449+
fields.insert(
450+
"a".to_string(),
451+
Value {
452+
kind: Some(Kind::NumberValue(1.0)),
453+
},
454+
);
455+
fields.insert(
456+
"b".to_string(),
457+
Value {
458+
kind: Some(Kind::NumberValue(2.0)),
459+
},
460+
);
461+
fields
462+
};
463+
464+
let expected = Value {
465+
kind: Some(Kind::StructValue(Struct {
466+
fields: expected_fields,
467+
})),
468+
};
469+
470+
assert_eq!(map.to_value(), expected);
471+
}
272472
}

0 commit comments

Comments
 (0)