Skip to content

Commit 6ee5973

Browse files
committed
feat: added std::object::get
1 parent bf96175 commit 6ee5973

1 file changed

Lines changed: 108 additions & 0 deletions

File tree

crates/core/src/runtime/functions/object.rs

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::context::context::Context;
55
use crate::context::macros::args;
66
use crate::context::registry::{HandlerFn, HandlerFunctionEntry, IntoFunctionEntry};
77
use crate::context::signal::Signal;
8+
use crate::runtime::error::RuntimeError;
89
use crate::value::value_from_i64;
910

1011
pub fn collect_object_functions() -> Vec<(&'static str, HandlerFunctionEntry)> {
@@ -16,6 +17,7 @@ pub fn collect_object_functions() -> Vec<(&'static str, HandlerFunctionEntry)> {
1617
("std::object::keys", HandlerFn::eager(keys, 1)),
1718
("std::object::size", HandlerFn::eager(size, 1)),
1819
("std::object::set", HandlerFn::eager(set, 3)),
20+
("std::object::get", HandlerFn::eager(get, 2)),
1921
]
2022
}
2123

@@ -74,6 +76,22 @@ fn set(
7476
kind: Some(Kind::StructValue(new_object)),
7577
})
7678
}
79+
80+
fn get(
81+
args: &[Argument],
82+
_ctx: &mut Context,
83+
_run: &mut dyn FnMut(i64, &mut Context) -> Signal,
84+
) -> Signal {
85+
args!(args => object: Struct, key: String);
86+
match object.fields.get(&key) {
87+
Some(v) => Signal::Success(v.clone()),
88+
None => Signal::Failure(RuntimeError::simple(
89+
"FieldNotPresent",
90+
format!("field {} not present", key),
91+
)),
92+
}
93+
}
94+
7795
#[cfg(test)]
7896
mod tests {
7997
use super::*;
@@ -410,4 +428,94 @@ mod tests {
410428
assert_eq!(orig_clone.fields.len(), original_len);
411429
assert!(!orig_clone.fields.contains_key("new_key"));
412430
}
431+
432+
#[test]
433+
fn test_get_success_string_field() {
434+
let mut ctx = Context::default();
435+
let mut run = dummy_run;
436+
let args = vec![a_struct(s_test()), a_string("name")];
437+
438+
let signal = get(&args, &mut ctx, &mut run);
439+
let v = match signal {
440+
Signal::Success(v) => v,
441+
s => panic!("Expected Success, got {:?}", s),
442+
};
443+
444+
match v.kind {
445+
Some(Kind::StringValue(s)) => assert_eq!(s, "John"),
446+
_ => panic!("Expected StringValue"),
447+
}
448+
}
449+
450+
#[test]
451+
fn test_get_success_nested_struct_field() {
452+
let mut ctx = Context::default();
453+
let nested = {
454+
let mut nf = HashMap::new();
455+
nf.insert("street".to_string(), v_string("123 Main St"));
456+
v_struct(nf)
457+
};
458+
let object = s_from(vec![("address", nested)]);
459+
let mut run = dummy_run;
460+
let args = vec![a_struct(object), a_string("address")];
461+
462+
let signal = get(&args, &mut ctx, &mut run);
463+
let v = match signal {
464+
Signal::Success(v) => v,
465+
s => panic!("Expected Success, got {:?}", s),
466+
};
467+
468+
match v.kind {
469+
Some(Kind::StructValue(st)) => {
470+
match st.fields.get("street") {
471+
Some(Value {
472+
kind: Some(Kind::StringValue(s)),
473+
..
474+
}) => assert_eq!(s, "123 Main St"),
475+
_ => panic!("Expected nested 'street' string"),
476+
}
477+
}
478+
_ => panic!("Expected StructValue"),
479+
}
480+
}
481+
482+
#[test]
483+
fn test_get_missing_field_returns_field_not_present() {
484+
let mut ctx = Context::default();
485+
let mut run = dummy_run;
486+
let args = vec![a_struct(s_test()), a_string("email")];
487+
488+
let signal = get(&args, &mut ctx, &mut run);
489+
let err = match signal {
490+
Signal::Failure(err) => err,
491+
s => panic!("Expected Failure, got {:?}", s),
492+
};
493+
494+
assert_eq!(err.name, "FieldNotPresent");
495+
assert_eq!(err.message, "field email not present");
496+
}
497+
498+
#[test]
499+
fn test_collect_object_functions_registers_get_handler() {
500+
let mut ctx = Context::default();
501+
let mut run = dummy_run;
502+
let args = vec![a_struct(s_test()), a_string("age")];
503+
504+
let entry = collect_object_functions()
505+
.into_iter()
506+
.find(|(id, _)| *id == "std::object::get")
507+
.map(|(_, entry)| entry)
508+
.expect("std::object::get should be registered");
509+
510+
let signal = (entry.handler)(&args, &mut ctx, &mut run);
511+
let v = match signal {
512+
Signal::Success(v) => v,
513+
s => panic!("Expected Success, got {:?}", s),
514+
};
515+
516+
match v.kind {
517+
Some(Kind::NumberValue(n)) => assert_eq!(number_to_f64(&n).unwrap_or_default(), 30.0),
518+
_ => panic!("Expected NumberValue"),
519+
}
520+
}
413521
}

0 commit comments

Comments
 (0)