Create ion macros that generate code from Ion text
Application specific code that generates Ion often generates very similar Ion over and over. As an Ion user, it would be nice to have a macro that can evaluate Ion text at compile time and turn it into code for a programmatically constructed IonElement instance. E.g.:
let foo = ion_element!("foo::{ bar: 1, baz: 2 }");
On its own, this might be useful as a test utility, but on the whole it's a bit of a toy example. To make it really useful, it should support some sort of interpolation/templating, like the format!() family of macros. E.g.
use ion_rs::value::owned::Element
struct IslRange {
start: i64,
end: i64,
}
impl From<IslRange> for Element {
fn from(value: IslRange) -> Self {
ion_element!("range::[ {}, {} ]", value.start, value.end)
// Expands to:
// Element::new(
// vec!["range".into()],
// Value::List(
// Sequence::new(
// vec![value.start.into(), value.end.into()]
// )
// )
// )
}
}
Now, it's quite powerful. Obviously, the {} syntax wouldn't work because it would get confused with an empty struct, but the exact syntax is a secondary issue to figure out.
Taking this one step further, we could even generate code that bypasses the DOM and can write directly to an IonWriter. This would save users from having to write code to add annotations, step in/out, etc., but they could still get the efficiency benefits of writing directly to an IonWriter. (And we could basically end up with most of a serde/databinding framework for Ion.) E.g.:
// Provided by ion-rs, perhaps
trait WriteIon {
fn write_to(&self, writer: &dyn IonWriter);
}
// In an Ion user's code:
#[derive(WriteIon)]
#[ion("range::[ {self.start}, {self.end} ]")]
struct IslRange {
start: i64,
end: i64,
}
...but I digress. My point is that there are some Ion macros that would be really useful even if they aren't a full serde/databinding framework. (And they could still be useful, incremental progress towards a databinding framework.)