litl 0.6.0

A JSON dialect with support for tagged binary data
Documentation
use std::borrow::Borrow;

use serde::{de::Error, Deserialize, Deserializer, Serializer};

#[inline]
pub fn raw_data_to_litl(val: &[u8]) -> String {
    format!("h{}", zbase32::encode(val))
}

#[inline]
pub fn serialize<S, T: Borrow<[u8]>>(val: &T, s: S) -> Result<S::Ok, S::Error>
where
    S: Serializer,
{
    s.serialize_str(&raw_data_to_litl(val.borrow()))
}

#[inline]
pub fn raw_data_from_litl(val: litl_val::Val) -> Result<Vec<u8>, String> {
    if let Some(data_str) = val.as_str().and_then(|s| s.strip_prefix('h')) {
        zbase32::decode(data_str).map_err(|err| err.to_string())
    } else {
        Err("Expected zbase32 encoded data".to_string())
    }
}

#[inline]
pub fn deserialize<'de, D, T: From<Vec<u8>>>(d: D) -> Result<T, D::Error>
where
    D: Deserializer<'de>,
{
    // TODO: figure out how to avoid string allocation when we can borrow
    let s = String::deserialize(d)?;
    if let Some(data_str) = s.strip_prefix('h') {
        let data = zbase32::decode(data_str)
            .map_err(D::Error::custom)?;
        Ok(data.into())
    } else {
        Err(D::Error::custom("Expected zbase32 encoded data"))
    }
}