sway_core/language/
purity.rs

1use serde::{Deserialize, Serialize};
2
3use sway_ast::attribute::{STORAGE_READ_ARG_NAME, STORAGE_WRITE_ARG_NAME};
4
5/// The purity of a function is related to its access of contract storage. If a function accesses
6/// or could potentially access contract storage, it is [Purity::Impure]. If a function does not utilize any
7/// any accesses (reads _or_ writes) of storage, then it is [Purity::Pure].
8#[derive(Clone, Debug, Copy, PartialEq, Eq, Hash, Default, Serialize, Deserialize)]
9pub enum Purity {
10    #[default]
11    Pure,
12    Reads,
13    Writes,
14    ReadsWrites,
15}
16
17impl Purity {
18    pub fn can_call(&self, other: Purity) -> bool {
19        match self {
20            Purity::Pure => other == Purity::Pure,
21            Purity::Reads => other == Purity::Pure || other == Purity::Reads,
22            Purity::Writes => true, // storage(write) allows reading as well
23            Purity::ReadsWrites => true,
24        }
25    }
26
27    // Useful for error messages, show the syntax needed in the #[storage(...)] attribute.
28    pub fn to_attribute_syntax(&self) -> String {
29        match self {
30            Purity::Pure => "".to_owned(),
31            Purity::Reads => STORAGE_READ_ARG_NAME.to_owned(),
32            Purity::Writes => STORAGE_WRITE_ARG_NAME.to_owned(),
33            Purity::ReadsWrites => {
34                format!("{STORAGE_READ_ARG_NAME}, {STORAGE_WRITE_ARG_NAME}")
35            }
36        }
37    }
38}
39
40/// Utility to find the union of purities.  To 'promote' Reads to Writes we want ReadsWrites, and
41/// the same for Writes to Reads.
42pub fn promote_purity(from: Purity, to: Purity) -> Purity {
43    match (from, to) {
44        (Purity::Reads, Purity::Writes)
45        | (Purity::Writes, Purity::Reads)
46        | (Purity::ReadsWrites, _) => Purity::ReadsWrites,
47        _otherwise => to,
48    }
49}