From d6bddb8e1bab663bae1e84f8bcc1e08ef8f5d253 Mon Sep 17 00:00:00 2001 From: Devin Jean Date: Fri, 22 Sep 2023 15:14:42 -0500 Subject: [PATCH] loosen type restrictions for join block --- src/process.rs | 2 +- src/runtime.rs | 74 +++++++++++++--------- src/test/blocks/explicit-to-string-cvt.xml | 1 + src/test/process.rs | 26 ++++++++ 4 files changed, 73 insertions(+), 30 deletions(-) create mode 100644 src/test/blocks/explicit-to-string-cvt.xml diff --git a/src/process.rs b/src/process.rs index 63acdd0..90178eb 100644 --- a/src/process.rs +++ b/src/process.rs @@ -836,7 +836,7 @@ impl<'gc, C: CustomTypes, S: System> Process<'gc, C, S> { VariadicOp::StrCat => |_, _, values| { let mut acc = String::new(); for item in values { - acc.push_str(item.to_string()?.as_ref()); + core::fmt::write(&mut acc, format_args!("{item}")).unwrap(); } Ok(Rc::new(acc).into()) }, diff --git a/src/runtime.rs b/src/runtime.rs index 64ed68d..6502a9a 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -676,42 +676,58 @@ impl<'gc, C: CustomTypes, S: System> GetType for Value<'gc, C, S> { } } +#[derive(Clone, Copy)] +enum FormatStyle { + Debug, Display, +} impl, S: System> fmt::Debug for Value<'_, C, S> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fn print<'gc, C: CustomTypes, S: System>(value: &Value<'gc, C, S>, cache: &mut BTreeSet>, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match value { - Value::Bool(x) => write!(f, "{x}"), - Value::Number(x) => write!(f, "{x}"), - Value::String(x) => write!(f, "{:?}", x.as_str()), - Value::Closure(x) => write!(f, "{:?}", &*x.borrow()), - Value::Entity(x) => write!(f, "{:?}", &*x.borrow()), - Value::Native(x) => write!(f, "{:?}", &**x), - Value::Image(x) => write!(f, "[Image {:?}]", Rc::as_ptr(x)), - Value::Audio(x) => write!(f, "[Audio {:?}]", Rc::as_ptr(x)), - Value::List(x) => { - let identity = value.identity(); - if !cache.insert(identity) { return write!(f, "[...]") } - - let x = x.borrow(); - write!(f, "[")?; - for (i, val) in x.iter().enumerate() { - print(val, cache, f)?; - if i != x.len() - 1 { write!(f, ",")? } - } - write!(f, "]")?; - - debug_assert!(cache.contains(&identity)); - cache.remove(&identity); - Ok(()) + format_value(self, f, FormatStyle::Debug) + } +} +impl, S: System> fmt::Display for Value<'_, C, S> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + format_value(self, f, FormatStyle::Display) + } +} +fn format_value, S: System>(value: &Value<'_, C, S>, f: &mut fmt::Formatter<'_>, style: FormatStyle) -> fmt::Result { + fn print<'gc, C: CustomTypes, S: System>(value: &Value<'gc, C, S>, f: &mut fmt::Formatter<'_>, style: FormatStyle, cache: &mut BTreeSet>) -> fmt::Result { + match value { + Value::Bool(x) => write!(f, "{x}"), + Value::Number(x) => write!(f, "{x}"), + Value::String(x) => match style { + FormatStyle::Debug => write!(f, "{:?}", x.as_str()), + FormatStyle::Display => write!(f, "{}", x.as_str()), + } + Value::Closure(x) => write!(f, "{:?}", &*x.borrow()), + Value::Entity(x) => write!(f, "{:?}", &*x.borrow()), + Value::Native(x) => write!(f, "{:?}", &**x), + Value::Image(x) => write!(f, "[Image {:?}]", Rc::as_ptr(x)), + Value::Audio(x) => write!(f, "[Audio {:?}]", Rc::as_ptr(x)), + Value::List(x) => { + let identity = value.identity(); + if !cache.insert(identity) { return write!(f, "[...]") } + + let x = x.borrow(); + write!(f, "[")?; + for (i, val) in x.iter().enumerate() { + print(val, f, style, cache)?; + if i != x.len() - 1 { write!(f, ",")? } } + write!(f, "]")?; + + debug_assert!(cache.contains(&identity)); + cache.remove(&identity); + Ok(()) } } - let mut cache = Default::default(); - let res = print(self, &mut cache, f); - if res.is_ok() { debug_assert_eq!(cache.len(), 0); } - res } + let mut cache = Default::default(); + let res = print(value, f, style, &mut cache); + if res.is_ok() { debug_assert_eq!(cache.len(), 0); } + res } + impl<'gc, C: CustomTypes, S: System> From for Value<'gc, C, S> { fn from(v: bool) -> Self { Value::Bool(v) } } impl<'gc, C: CustomTypes, S: System> From for Value<'gc, C, S> { fn from(v: Number) -> Self { Value::Number(v) } } impl<'gc, C: CustomTypes, S: System> From> for Value<'gc, C, S> { fn from(v: Rc) -> Self { Value::String(v) } } diff --git a/src/test/blocks/explicit-to-string-cvt.xml b/src/test/blocks/explicit-to-string-cvt.xml new file mode 100644 index 0000000..a062114 --- /dev/null +++ b/src/test/blocks/explicit-to-string-cvt.xml @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/src/test/process.rs b/src/test/process.rs index bb986f1..ace12f4 100644 --- a/src/test/process.rs +++ b/src/test/process.rs @@ -1563,6 +1563,32 @@ fn test_proc_list_json() { }); } +#[test] +fn test_proc_explicit_to_string_cvt() { + let system = Rc::new(StdSystem::new_sync(BASE_URL.to_owned(), None, Config::default(), UtcOffset::UTC)); + let (mut env, _) = get_running_proc(&format!(include_str!("templates/generic-static.xml"), + globals = "", + fields = "", + funcs = include_str!("blocks/explicit-to-string-cvt.xml"), + methods = "", + ), Settings::default(), system); + + run_till_term(&mut env, |mc, _, res| { + let expect = Value::from_json(mc, json!([ + "hello world 1", + "hello 67 2", + "hello 69 3", + "hello true 4", + "hello false 5", + "hello [] 6", + "hello [test] 7", + "hello [test,more] 8", + "hello [1,2,3,4] 9", + ])).unwrap(); + assert_values_eq(&res.unwrap().0.unwrap(), &expect, 1e-5, "explicit tostr"); + }); +} + #[test] fn test_proc_signed_zero() { let system = Rc::new(StdSystem::new_sync(BASE_URL.to_owned(), None, Config::default(), UtcOffset::UTC));