oxyroot 0.1.25

Another attempt to make library reading and writing of `.root` binary files which are commonly used in particle physics
Documentation
use crate::root::traits;
use crate::rtypes::factory::{Factory, FactoryBuilder};
use crate::rtypes::FactoryItemRead;
use crate::{rbase, Object, RBuffer, Unmarshaler};
use log::trace;
use std::collections::HashMap;

#[derive(Eq, Hash, PartialEq)]
pub enum Key {
    String(String),
}

#[derive(Default)]
pub struct TMap {
    name: Option<String>,
    obj: rbase::Object,
    objs: HashMap<Key, Box<dyn FactoryItemRead>>,
}

impl TMap {
    pub fn get<T: 'static>(&self, key: &Key) -> Option<&T> {
        match self.objs.get(key) {
            None => None,
            Some(v) => Some(v.downcast_ref::<T>().unwrap()),
        }
    }
}

impl FactoryBuilder for TMap {
    fn register(factory: &mut Factory) {
        let f = || {
            let v = TMap::default();
            let b: Box<dyn FactoryItemRead> = Box::new(v);
            b
        };

        factory.add("TMap", f);
    }
}

impl Object for TMap {
    fn class(&self) -> &'_ str {
        "TMap"
    }
}

impl traits::Named for TMap {
    fn name(&self) -> &'_ str {
        match &self.name {
            None => "TList",
            Some(s) => s,
        }
    }

    fn title(&self) -> &'_ str {
        "A (key,value) map"
    }
}

impl Unmarshaler for TMap {
    fn unmarshal(&mut self, r: &mut RBuffer) -> crate::rbytes::Result<()> {
        let hdr = r.read_header(self.class())?;

        if hdr.vers > 2 {
            r.read_object(&mut self.obj)?;
        }

        if hdr.vers > 1 {
            self.name = Some(r.read_string()?.to_string());
        }

        let nobjs = r.read_i32()?;

        trace!(";TMap.unmarshal.nobjs={}", nobjs);

        for _ in 0..nobjs {
            let key = r.read_object_any_into()?.unwrap();
            trace!(";TMap.unmarshal.key={:?}", key);

            let value = r.read_object_any_into()?.unwrap();

            match key.class() {
                "TObjString" => {
                    let key = key.downcast_ref::<crate::rbase::TObjString>().unwrap();
                    self.objs.insert(Key::String(key.to_string()), value);
                }
                _ => {
                    unimplemented!("TMap.unmarshal: key class={}", key.class());
                }
            }
        }

        Ok(())
    }
}