twinleaf 1.9.0

Library for working with the Twinleaf I/O protocol and Twinleaf quantum sensors.
Documentation
use super::client::RpcList;
use super::meta::RpcMeta;
use std::collections::{BTreeMap, BTreeSet};

#[derive(Debug, Clone)]
pub struct RpcDescriptor {
    pub full_name: String,
    pub meta: RpcMeta,
}

impl RpcDescriptor {
    pub fn from_meta(meta: u16, name: String) -> RpcDescriptor {
        RpcDescriptor {
            full_name: name,
            meta: RpcMeta::from_bits(meta),
        }
    }
}

pub struct RpcRegistry {
    rpcs: BTreeMap<String, RpcDescriptor>,
    pub hash: Option<u32>,
}

impl RpcRegistry {
    pub fn new(specs: Vec<RpcDescriptor>) -> Self {
        let rpcs = specs
            .into_iter()
            .map(|spec| (spec.full_name.clone(), spec))
            .collect();
        Self { rpcs, hash: None }
    }

    pub fn find(&self, name: &str) -> Option<&RpcDescriptor> {
        self.rpcs.get(name)
    }

    pub fn names(&self) -> Vec<String> {
        self.rpcs.keys().cloned().collect()
    }

    pub fn name_set(&self) -> BTreeSet<String> {
        self.rpcs.keys().cloned().collect()
    }

    pub fn iter(&self) -> impl Iterator<Item = &RpcDescriptor> + '_ {
        self.rpcs.values()
    }

    pub fn children_of(&self, prefix: &str) -> Vec<String> {
        let lo = if prefix.is_empty() {
            String::new()
        } else {
            format!("{prefix}.")
        };
        let mut out: Vec<String> = Vec::new();
        for (name, _) in self.rpcs.range(lo.clone()..) {
            let Some(rest) = name.strip_prefix(&lo) else {
                break;
            };
            let seg = rest.split('.').next().unwrap_or(rest);
            if out.last().map(String::as_str) != Some(seg) {
                out.push(seg.to_string());
            }
        }
        out
    }
}

impl From<&RpcList> for RpcRegistry {
    fn from(list: &RpcList) -> Self {
        let specs = list
            .vec
            .iter()
            .map(|(name, meta)| RpcDescriptor::from_meta(*meta, name.clone()))
            .collect();
        let mut registry = Self::new(specs);
        registry.hash = Some(list.hash);
        registry
    }
}