sway_core/language/parsed/declaration/
storage.rs

1use crate::{
2    engine_threading::{EqWithEngines, PartialEqWithEngines, PartialEqWithEnginesContext},
3    language::parsed::Expression,
4    transform,
5    type_system::*,
6};
7use sway_types::{ident::Ident, span::Span, Spanned};
8
9#[derive(Debug, Clone)]
10/// A declaration of contract storage. Only valid within contract contexts.
11/// All values in this struct are mutable and persistent among executions of the same contract deployment.
12pub struct StorageDeclaration {
13    pub attributes: transform::Attributes,
14    pub entries: Vec<StorageEntry>,
15    pub span: Span,
16    pub storage_keyword: Ident,
17}
18
19impl EqWithEngines for StorageDeclaration {}
20impl PartialEqWithEngines for StorageDeclaration {
21    fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
22        self.attributes == other.attributes
23            && self.entries.eq(&other.entries, ctx)
24            && self.span == other.span
25            && self.storage_keyword == other.storage_keyword
26    }
27}
28
29impl Spanned for StorageDeclaration {
30    fn span(&self) -> sway_types::Span {
31        self.span.clone()
32    }
33}
34
35#[derive(Debug, Clone)]
36pub struct StorageNamespace {
37    pub name: Ident,
38    pub entries: Vec<Box<StorageEntry>>,
39}
40
41impl EqWithEngines for StorageNamespace {}
42impl PartialEqWithEngines for StorageNamespace {
43    fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
44        self.name.eq(&other.name) && self.entries.eq(&other.entries, ctx)
45    }
46}
47
48#[allow(clippy::large_enum_variant)]
49#[derive(Debug, Clone)]
50pub enum StorageEntry {
51    Namespace(StorageNamespace),
52    Field(StorageField),
53}
54
55impl StorageEntry {
56    pub fn name(&self) -> Ident {
57        match self {
58            StorageEntry::Namespace(namespace) => namespace.name.clone(),
59            StorageEntry::Field(field) => field.name.clone(),
60        }
61    }
62}
63
64impl EqWithEngines for StorageEntry {}
65impl PartialEqWithEngines for StorageEntry {
66    fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
67        match (self, other) {
68            (StorageEntry::Namespace(n1), StorageEntry::Namespace(n2)) => n1.eq(n2, ctx),
69            (StorageEntry::Field(f1), StorageEntry::Field(f2)) => f1.eq(f2, ctx),
70            _ => false,
71        }
72    }
73}
74
75/// An individual field in a storage declaration.
76/// A type annotation _and_ initializer value must be provided. The initializer value must be a
77/// constant expression. For now, that basically means just a literal, but as constant folding
78/// improves, we can update that.
79#[derive(Debug, Clone)]
80pub struct StorageField {
81    pub name: Ident,
82    pub key_expression: Option<Expression>,
83    pub attributes: transform::Attributes,
84    pub type_argument: GenericTypeArgument,
85    pub span: Span,
86    pub initializer: Expression,
87}
88
89impl EqWithEngines for StorageField {}
90impl PartialEqWithEngines for StorageField {
91    fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
92        self.name == other.name
93            && self.attributes == other.attributes
94            && self.type_argument.eq(&other.type_argument, ctx)
95            && self.span == other.span
96            && self.initializer.eq(&other.initializer, ctx)
97    }
98}