use alloc::{boxed::Box, collections::BTreeMap, format, vec::Vec};
use core::{
any::{Any, TypeId},
fmt::{Debug, Pointer},
};
use crate::{errors::DecodeError, span::Span};
#[derive(Debug, Default)]
pub struct Context {
pub spans: BTreeMap<Box<str>, Span>,
pub errors: Vec<DecodeError>,
extensions: BTreeMap<TypeId, Box<dyn Any>>,
}
impl Context {
pub(crate) fn new() -> Context {
Context {
spans: BTreeMap::new(),
errors: Vec::new(),
extensions: BTreeMap::new(),
}
}
pub(crate) fn set_span<P: Pointer + Debug>(&mut self, pointer: &P, span: Span) {
self.spans
.insert(format!("{:p}", pointer).into_boxed_str(), span);
}
#[allow(unused_variables)]
pub fn span<P: Pointer + Debug>(&self, pointer: &P) -> Span {
Span(0, 0)
}
pub fn emit_error(&mut self, err: impl Into<DecodeError>) {
self.errors.push(err.into());
}
pub fn has_errors(&self) -> bool {
!self.errors.is_empty()
}
pub fn set<T: 'static>(&mut self, value: T) {
self.extensions.insert(TypeId::of::<T>(), Box::new(value));
}
pub fn get<T: 'static>(&self) -> Option<&T> {
self.extensions
.get(&TypeId::of::<T>())
.and_then(|b| b.downcast_ref())
}
}