sway_core/language/
purity.rs

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