mathtex-editor-session 0.3.0

Batteries included session for mathtex-editor: keymap, typesetting, undo, clipboard and host box tokens over the explicit core
Documentation
use std::collections::{BTreeSet, HashMap};

use mathtex_engine::{HostBox, HostBoxRequest, HostBoxes};
use mathtex_ir::Length;

/// The session's answer to `\hostbox`: sizes the host set by token first, then the host's provider.
#[derive(Default)]
pub(crate) struct SessionBoxes {
    /// `(width, height, depth, revision)` by token.
    sizes: HashMap<u32, (Length, Length, Length, u64)>,
    provider: Option<Box<dyn HostBoxes>>,
    counter: u64,
}

impl SessionBoxes {
    pub(crate) fn set_size(&mut self, token: u32, width: Length, height: Length, depth: Length) {
        self.counter += 1;
        self.sizes.insert(token, (width, height, depth, self.counter));
    }

    /// Give `new` the size `old` has, so a reminted paste keeps its layout.
    pub(crate) fn copy_size(&mut self, old: u32, new: u32) {
        if let Some(&(w, h, d, _)) = self.sizes.get(&old) {
            self.set_size(new, w, h, d);
        }
    }

    pub(crate) fn set_provider(&mut self, provider: Option<Box<dyn HostBoxes>>) {
        self.provider = provider;
    }

    pub(crate) fn retain(&mut self, live: &BTreeSet<u32>) {
        self.sizes.retain(|token, _| live.contains(token));
    }
}

impl HostBoxes for SessionBoxes {
    fn host_box(&self, request: &HostBoxRequest) -> Option<HostBox> {
        match self.sizes.get(&request.token) {
            Some(&(w, h, d, _)) => Some(HostBox::new(w, h, d)),
            None => self.provider.as_ref()?.host_box(request),
        }
    }

    fn revision(&self, token: u32) -> Option<u64> {
        match (self.sizes.get(&token), &self.provider) {
            // The top bit keeps size revisions apart from the provider's and from the 0 of an unknown token.
            (Some(&(.., revision)), _) => Some(revision | 1 << 63),
            (None, Some(provider)) => provider.revision(token),
            (None, None) => Some(0),
        }
    }
}