use shape_value::KindedSlot;
use std::collections::HashMap;
#[derive(Clone)]
pub struct AnnotationRegistry {
annotations: HashMap<String, shape_ast::ast::AnnotationDef>,
}
impl AnnotationRegistry {
pub fn new() -> Self {
Self {
annotations: HashMap::new(),
}
}
pub fn register(&mut self, def: shape_ast::ast::AnnotationDef) {
self.annotations.insert(def.name.clone(), def);
}
pub fn get(&self, name: &str) -> Option<&shape_ast::ast::AnnotationDef> {
self.annotations.get(name)
}
pub fn contains(&self, name: &str) -> bool {
self.annotations.contains_key(name)
}
}
impl Default for AnnotationRegistry {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone)]
pub struct AnnotationContext {
cache: AnnotationCache,
state: AnnotationState,
registries: HashMap<String, NamedRegistry>,
events: Vec<EmittedEvent>,
data_range: DataRangeState,
}
impl AnnotationContext {
pub fn new() -> Self {
Self {
cache: AnnotationCache::new(),
state: AnnotationState::new(),
registries: HashMap::new(),
events: Vec::new(),
data_range: DataRangeState::new(),
}
}
pub fn cache(&self) -> &AnnotationCache {
&self.cache
}
pub fn cache_mut(&mut self) -> &mut AnnotationCache {
&mut self.cache
}
pub fn state(&self) -> &AnnotationState {
&self.state
}
pub fn state_mut(&mut self) -> &mut AnnotationState {
&mut self.state
}
pub fn registry(&mut self, name: &str) -> &mut NamedRegistry {
self.registries.entry(name.to_string()).or_default()
}
pub fn emit(&mut self, event_type: &str, data: KindedSlot) {
self.events.push(EmittedEvent {
event_type: event_type.to_string(),
data,
timestamp: std::time::Instant::now(),
});
}
pub fn events(&self) -> &[EmittedEvent] {
&self.events
}
pub fn clear_events(&mut self) {
self.events.clear();
}
pub fn data_range(&self) -> &DataRangeState {
&self.data_range
}
pub fn data_range_mut(&mut self) -> &mut DataRangeState {
&mut self.data_range
}
}
impl Default for AnnotationContext {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone, Default)]
pub struct AnnotationCache {
entries: HashMap<String, CacheEntry>,
}
#[derive(Debug, Clone)]
pub struct CacheEntry {
pub value: KindedSlot,
pub created_at: std::time::Instant,
}
impl AnnotationCache {
pub fn new() -> Self {
Self {
entries: HashMap::new(),
}
}
pub fn get(&self, key: &str) -> Option<&KindedSlot> {
self.entries.get(key).map(|e| &e.value)
}
pub fn get_entry(&self, key: &str) -> Option<&CacheEntry> {
self.entries.get(key)
}
pub fn set(&mut self, key: String, value: KindedSlot) {
self.entries.insert(
key,
CacheEntry {
value,
created_at: std::time::Instant::now(),
},
);
}
pub fn contains(&self, key: &str) -> bool {
self.entries.contains_key(key)
}
pub fn remove(&mut self, key: &str) -> Option<KindedSlot> {
self.entries.remove(key).map(|e| e.value)
}
pub fn clear(&mut self) {
self.entries.clear();
}
}
#[derive(Debug, Clone, Default)]
pub struct AnnotationState {
values: HashMap<String, KindedSlot>,
}
impl AnnotationState {
pub fn new() -> Self {
Self {
values: HashMap::new(),
}
}
pub fn get(&self, key: &str) -> Option<&KindedSlot> {
self.values.get(key)
}
pub fn set(&mut self, key: String, value: KindedSlot) {
self.values.insert(key, value);
}
pub fn contains(&self, key: &str) -> bool {
self.values.contains_key(key)
}
pub fn remove(&mut self, key: &str) -> Option<KindedSlot> {
self.values.remove(key)
}
pub fn clear(&mut self) {
self.values.clear();
}
}
#[derive(Debug, Clone, Default)]
pub struct NamedRegistry {
entries: HashMap<String, KindedSlot>,
}
impl NamedRegistry {
pub fn new() -> Self {
Self {
entries: HashMap::new(),
}
}
pub fn get(&self, key: &str) -> Option<&KindedSlot> {
self.entries.get(key)
}
pub fn set(&mut self, key: String, value: KindedSlot) {
self.entries.insert(key, value);
}
pub fn contains(&self, key: &str) -> bool {
self.entries.contains_key(key)
}
pub fn remove(&mut self, key: &str) -> Option<KindedSlot> {
self.entries.remove(key)
}
pub fn keys(&self) -> impl Iterator<Item = &String> {
self.entries.keys()
}
pub fn values(&self) -> impl Iterator<Item = &KindedSlot> {
self.entries.values()
}
pub fn len(&self) -> usize {
self.entries.len()
}
pub fn is_empty(&self) -> bool {
self.entries.is_empty()
}
}
#[derive(Debug, Clone)]
pub struct EmittedEvent {
pub event_type: String,
pub data: KindedSlot,
pub timestamp: std::time::Instant,
}
#[derive(Debug, Clone, Default)]
pub struct DataRangeState {
original_start: Option<usize>,
original_end: Option<usize>,
extension_amount: Option<usize>,
}
impl DataRangeState {
pub fn new() -> Self {
Self {
original_start: None,
original_end: None,
extension_amount: None,
}
}
pub fn save_original(&mut self, start: usize, end: usize) {
self.original_start = Some(start);
self.original_end = Some(end);
}
pub fn set_extension(&mut self, amount: usize) {
self.extension_amount = Some(amount);
}
pub fn original_start(&self) -> Option<usize> {
self.original_start
}
pub fn original_end(&self) -> Option<usize> {
self.original_end
}
pub fn extension_amount(&self) -> Option<usize> {
self.extension_amount
}
pub fn is_extended(&self) -> bool {
self.extension_amount.is_some()
}
pub fn clear(&mut self) {
self.original_start = None;
self.original_end = None;
self.extension_amount = None;
}
}