serde_toon_format 0.1.2

Serde-compatible TOON v3.0 encoder/decoder
Documentation
use smol_str::SmolStr;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum NodeKind {
    Null,
    Bool,
    Number,
    String,
    Array,
    Object,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum NodeData {
    None,
    Bool(bool),
    String(usize),
    Number(usize),
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Span {
    pub start: usize,
    pub end: usize,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum StringRef {
    Span(Span),
    Owned(String),
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Pair {
    pub key: usize,
    pub value: usize,
}

#[derive(Debug)]
pub struct Node {
    pub kind: NodeKind,
    pub first_child: usize,
    pub child_len: usize,
    pub data: NodeData,
}

#[derive(Debug, Default)]
pub struct Arena {
    pub nodes: Vec<Node>,
    pub strings: Vec<String>,
    pub numbers: Vec<String>,
    pub children: Vec<usize>,
    pub pairs: Vec<Pair>,
    pub keys: Vec<SmolStr>,
}

impl Arena {
    pub fn new() -> Self {
        Self::default()
    }
}

#[derive(Debug, Default)]
pub struct ArenaParts {
    pub nodes: Vec<Node>,
    pub strings: Vec<StringRef>,
    pub numbers: Vec<Span>,
    pub children: Vec<usize>,
    pub pairs: Vec<Pair>,
    pub keys: Vec<SmolStr>,
}

impl ArenaParts {
    pub fn new() -> Self {
        Self::default()
    }

    pub fn clear(&mut self) {
        self.nodes.clear();
        self.strings.clear();
        self.numbers.clear();
        self.children.clear();
        self.pairs.clear();
        self.keys.clear();
    }
}

#[derive(Debug)]
pub struct ArenaView<'a> {
    pub input: &'a str,
    pub nodes: Vec<Node>,
    pub strings: Vec<StringRef>,
    pub numbers: Vec<Span>,
    pub children: Vec<usize>,
    pub pairs: Vec<Pair>,
    pub keys: Vec<SmolStr>,
}

impl<'a> ArenaView<'a> {
    pub fn new(input: &'a str) -> Self {
        Self {
            input,
            nodes: Vec::new(),
            strings: Vec::new(),
            numbers: Vec::new(),
            children: Vec::new(),
            pairs: Vec::new(),
            keys: Vec::new(),
        }
    }

    pub fn with_parts(input: &'a str, mut parts: ArenaParts) -> Self {
        parts.clear();
        Self {
            input,
            nodes: parts.nodes,
            strings: parts.strings,
            numbers: parts.numbers,
            children: parts.children,
            pairs: parts.pairs,
            keys: parts.keys,
        }
    }

    pub fn into_parts(self) -> ArenaParts {
        ArenaParts {
            nodes: self.nodes,
            strings: self.strings,
            numbers: self.numbers,
            children: self.children,
            pairs: self.pairs,
            keys: self.keys,
        }
    }

    pub fn get_str(&self, index: usize) -> Option<&str> {
        match self.strings.get(index)? {
            StringRef::Span(span) => self.input.get(span.start..span.end),
            StringRef::Owned(value) => Some(value.as_str()),
        }
    }

    pub fn get_num_str(&self, index: usize) -> Option<&'a str> {
        let span = self.numbers.get(index)?;
        self.input.get(span.start..span.end)
    }

    pub fn get_key(&self, index: usize) -> Option<&str> {
        self.keys.get(index).map(|key| key.as_str())
    }

    pub fn children(&self, node: &Node) -> &[usize] {
        let start = node.first_child;
        let end = start.saturating_add(node.child_len);
        self.children.get(start..end).unwrap_or(&[])
    }

    pub fn pairs(&self, node: &Node) -> &[Pair] {
        let start = node.first_child;
        let end = start.saturating_add(node.child_len);
        self.pairs.get(start..end).unwrap_or(&[])
    }
}