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