conjure_cp_core/ast/
metadata.rs1use crate::ast::versioned_cache::VersionedCache;
2use crate::ast::{DomainPtr, ReturnType, declaration::declaration_content_generation};
3use polyquine::Quine;
4use proc_macro2::TokenStream;
5use quote::quote;
6use serde::{Deserialize, Serialize};
7use std::fmt::{Debug, Display};
8use std::hash::Hash;
9use std::sync::atomic::{AtomicU64, Ordering};
10use uniplate::derive_unplateable;
11
12derive_unplateable!(Metadata);
13
14pub const NO_HASH: u64 = 0;
15#[derive(Debug, Deserialize, Serialize)]
19pub struct Metadata {
20 pub etype: Option<ReturnType>,
22 #[serde(default, skip_serializing_if = "Option::is_none")]
24 pub span_id: Option<u32>,
25 #[serde(default, skip_serializing)]
27 pub cached_content_hash: AtomicU64,
28 #[serde(skip)]
37 domain: VersionedCache<Option<DomainPtr>>,
38}
39
40impl Metadata {
41 pub fn new() -> Metadata {
43 Metadata {
44 etype: None,
45 span_id: None,
46 cached_content_hash: AtomicU64::new(NO_HASH),
47 domain: VersionedCache::new(),
48 }
49 }
50
51 pub fn with_span_id(span_id: u32) -> Metadata {
53 Metadata {
54 etype: None,
55 span_id: Some(span_id),
56 cached_content_hash: AtomicU64::new(NO_HASH),
57 domain: VersionedCache::new(),
58 }
59 }
60
61 pub fn clear_cached_domain(&self) {
63 self.domain.clear();
64 }
65
66 pub fn domain_or_init(
69 &self,
70 mut compute: impl FnMut() -> Option<DomainPtr>,
71 ) -> Option<DomainPtr> {
72 self.domain
73 .get_or_init(declaration_content_generation, |_| compute())
74 }
75}
76
77impl Default for Metadata {
78 fn default() -> Self {
79 Metadata::new()
80 }
81}
82
83impl Display for Metadata {
84 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
85 write!(f, "Metadata")
86 }
87}
88
89impl Hash for Metadata {
90 fn hash<H: std::hash::Hasher>(&self, _state: &mut H) {
91 }
93}
94
95impl Clone for Metadata {
96 fn clone(&self) -> Self {
97 Metadata {
98 etype: self.etype.clone(),
99 span_id: self.span_id,
100 cached_content_hash: AtomicU64::new(self.cached_content_hash.load(Ordering::Relaxed)),
101 domain: VersionedCache::new(),
107 }
108 }
109}
110
111impl PartialEq for Metadata {
112 fn eq(&self, other: &Self) -> bool {
113 self.etype == other.etype
114 }
115}
116
117impl Eq for Metadata {}
118
119impl Quine for Metadata {
120 fn ctor_tokens(&self) -> TokenStream {
121 let etype = self.etype.ctor_tokens();
122 let span_id = self.span_id.ctor_tokens();
123 quote! {{
124 let mut metadata = conjure_cp::ast::Metadata::new();
125 metadata.etype = #etype;
126 metadata.span_id = #span_id;
127 metadata
128 }}
129 }
130}