1
use crate::ast::ReturnType;
2
use polyquine::Quine;
3
use proc_macro2::TokenStream;
4
use quote::quote;
5
use serde::{Deserialize, Serialize};
6
use std::fmt::{Debug, Display};
7
use std::hash::Hash;
8
use std::sync::atomic::{AtomicU64, Ordering};
9
use uniplate::derive_unplateable;
10

            
11
derive_unplateable!(Metadata);
12

            
13
pub const NO_HASH: u64 = 0;
14

            
15
#[derive(Debug, Deserialize, Serialize, Default)]
16
pub struct Metadata {
17
    pub etype: Option<ReturnType>,
18
    #[serde(default, skip_serializing_if = "Option::is_none")]
19
    pub span_id: Option<u32>,
20
    #[serde(default, skip_serializing)]
21
    pub stored_hash: AtomicU64,
22
}
23

            
24
impl Metadata {
25
34103989
    pub fn new() -> Metadata {
26
34103989
        Metadata {
27
34103989
            etype: None,
28
34103989
            span_id: None,
29
34103989
            stored_hash: AtomicU64::new(NO_HASH),
30
34103989
        }
31
34103989
    }
32

            
33
    pub fn with_span_id(span_id: u32) -> Metadata {
34
        Metadata {
35
            etype: None,
36
            span_id: Some(span_id),
37
            stored_hash: AtomicU64::new(NO_HASH),
38
        }
39
    }
40
}
41

            
42
impl Display for Metadata {
43
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
44
        write!(f, "Metadata")
45
    }
46
}
47

            
48
impl Hash for Metadata {
49
    fn hash<H: std::hash::Hasher>(&self, _state: &mut H) {
50
        // Dummy method - Metadata is ignored when hashing an Expression
51
    }
52
}
53

            
54
impl Clone for Metadata {
55
10994701925
    fn clone(&self) -> Self {
56
10994701925
        Metadata {
57
10994701925
            etype: self.etype.clone(),
58
10994701925
            span_id: self.span_id,
59
10994701925
            stored_hash: AtomicU64::new(self.stored_hash.load(Ordering::Relaxed)),
60
10994701925
        }
61
10994701925
    }
62
}
63

            
64
impl PartialEq for Metadata {
65
190064788
    fn eq(&self, other: &Self) -> bool {
66
190064788
        self.etype == other.etype
67
190064788
    }
68
}
69

            
70
impl Eq for Metadata {}
71

            
72
impl Quine for Metadata {
73
1312
    fn ctor_tokens(&self) -> TokenStream {
74
1312
        let etype = self.etype.ctor_tokens();
75
1312
        let span_id = self.span_id.ctor_tokens();
76
1312
        quote! {
77
            conjure_cp::ast::Metadata {
78
                etype: #etype,
79
                span_id: #span_id,
80
                stored_hash: std::sync::atomic::AtomicU64::new(0),
81
            }
82
        }
83
1312
    }
84
}