litl-val 0.2.0

A memory efficient representation of JSON values
Documentation
use deepsize::DeepSizeOf;

use super::{key::Key, map_ref::MapRef, slim_boxed_slice::SlimBoxedSlice, val::Val};

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Map(SlimBoxedSlice<(Key, Val)>);

impl Map {
    pub fn new(mut entries: Vec<(Key, Val)>) -> Self {
        entries
            .as_mut_slice()
            .sort_by(|(k1, _), (k2, _)| k1.cmp(k2));
        Self(SlimBoxedSlice::from_vec(entries))
    }

    pub fn clone_from_ref(map: &MapRef) -> Self {
        Self(SlimBoxedSlice::from_vec(map.0.to_vec()))
    }

    pub fn get<K: AsRef<str>>(&self, key: K) -> Option<&Val> {
        self.0.as_ref().iter().find_map(|(k, v)| {
            if k.as_ref() == key.as_ref() {
                Some(v)
            } else {
                None
            }
        })
    }

    pub fn into_entries(self) -> ValMapEntries {
        ValMapEntries(self.0.into_vec())
    }

    pub fn into_raw(self) -> *mut () {
        self.0.into_raw()
    }

    pub unsafe fn from_raw(ptr: *mut ()) -> Self {
        Self(SlimBoxedSlice::from_raw(ptr))
    }

    pub fn entries(&self) -> &[(Key, Val)] {
        self.0.as_ref()
    }

    pub fn as_ref(&self) -> MapRef {
        MapRef(self.0.as_ref())
    }
}

impl DeepSizeOf for Map {
    fn deep_size_of_children(&self, context: &mut deepsize::Context) -> usize {
        self.0.deep_size_of_children(context)
    }
}

pub struct ValMapEntries(pub Vec<(Key, Val)>);

impl ValMapEntries {
    pub fn take<K: AsRef<str>>(&mut self, key: K) -> Option<Val> {
        self.0
            .iter()
            .position(|(k, _)| k.as_ref() == key.as_ref())
            .map(|i| self.0.swap_remove(i).1)
    }
}