Skip to content

Instantly share code, notes, and snippets.

@bwindels
Last active September 28, 2017 15:39
Show Gist options
  • Save bwindels/d845129c8a3c73ddbc5b9a965d13391e to your computer and use it in GitHub Desktop.
Save bwindels/d845129c8a3c73ddbc5b9a965d13391e to your computer and use it in GitHub Desktop.
Rust JSON parser with FieldRef
struct Foo<'a> {
age: u32,
name: &'a str,
}
pub enum FieldRef<'a, 'b: 'a> {
Str(&'a mut &'b str),
UInt32(&'a mut u32),
}
impl<'a, 'b> FieldRef<'a, 'b> {
pub fn offset_from(&self, root_offset: usize) -> usize {
let field_offset = match self {
&FieldRef::UInt32(ref r) => *r as *const u32 as usize,
&FieldRef::Str(ref r) => *r as *const &str as usize,
};
field_offset - root_offset
}
}
use self::FieldRef::*;
fn select_field<'a, 'b: 'a>(f: &'a mut Foo<'b>, field_name: &str) -> Option<FieldRef<'a, 'b>> {
match field_name {
"age" => Some(UInt32(&mut f.age)),
"name" => Some(Str(&mut f.name)),
_ => None,
}
}
fn fill_foo(f: &mut Foo) {
let offset : usize = f as *const Foo as usize;
for field_name in ["age", "name"].iter() {
if let Some(field_ref) = select_field(f, field_name) {
println!("offset for field {} is {:x}", field_name, field_ref.offset_from(offset));
match field_ref {
Str(str_ref) => *str_ref = "Vincent",
UInt32(uint_ref) => *uint_ref = 37u32,
}
}
}
}
fn main() {
let mut f: Foo = unsafe { std::mem::uninitialized() };
fill_foo(&mut f);
println!("{} is {:?} years old", f.name, f.age);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment