use ecow::{eco_format, EcoString};
use crate::diag::{At, SourceResult};
use crate::engine::Engine;
use crate::foundations::{func, scope, Bytes, Value};
use crate::syntax::Spanned;
use crate::World;
#[func(scope, title = "CBOR")]
pub fn cbor(
engine: &mut Engine,
path: Spanned<EcoString>,
) -> SourceResult<Value> {
let Spanned { v: path, span } = path;
let id = span.resolve_path(&path).at(span)?;
let data = engine.world.file(id).at(span)?;
cbor::decode(Spanned::new(data, span))
}
#[scope]
impl cbor {
#[func(title = "Decode CBOR")]
pub fn decode(
data: Spanned<Bytes>,
) -> SourceResult<Value> {
let Spanned { v: data, span } = data;
ciborium::from_reader(data.as_slice())
.map_err(|err| eco_format!("failed to parse CBOR ({err})"))
.at(span)
}
#[func(title = "Encode CBOR")]
pub fn encode(
value: Spanned<Value>,
) -> SourceResult<Bytes> {
let Spanned { v: value, span } = value;
let mut res = Vec::new();
ciborium::into_writer(&value, &mut res)
.map(|_| res.into())
.map_err(|err| eco_format!("failed to encode value as CBOR ({err})"))
.at(span)
}
}