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#[derive(Debug, Clone)]
49pub enum StorageEntry {
50    Namespace(StorageNamespace),
51    Field(StorageField),
52}
53
54impl StorageEntry {
55    pub fn name(&self) -> Ident {
56        match self {
57            StorageEntry::Namespace(namespace) => namespace.name.clone(),
58            StorageEntry::Field(field) => field.name.clone(),
59        }
60    }
61}
62
63impl EqWithEngines for StorageEntry {}
64impl PartialEqWithEngines for StorageEntry {
65    fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
66        match (self, other) {
67            (StorageEntry::Namespace(n1), StorageEntry::Namespace(n2)) => n1.eq(n2, ctx),
68            (StorageEntry::Field(f1), StorageEntry::Field(f2)) => f1.eq(f2, ctx),
69            _ => false,
70        }
71    }
72}
73
74/// An individual field in a storage declaration.
75/// A type annotation _and_ initializer value must be provided. The initializer value must be a
76/// constant expression. For now, that basically means just a literal, but as constant folding
77/// improves, we can update that.
78#[derive(Debug, Clone)]
79pub struct StorageField {
80    pub name: Ident,
81    pub key_expression: Option<Expression>,
82    pub attributes: transform::Attributes,
83    pub type_argument: GenericArgument,
84    pub span: Span,
85    pub initializer: Expression,
86}
87
88impl EqWithEngines for StorageField {}
89impl PartialEqWithEngines for StorageField {
90    fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
91        self.name == other.name
92            && self.attributes == other.attributes
93            && self.type_argument.eq(&other.type_argument, ctx)
94            && self.span == other.span
95            && self.initializer.eq(&other.initializer, ctx)
96    }
97}