Skip to main content

leo_ast/functions/
variant.rs

1// Copyright (C) 2019-2026 Provable Inc.
2// This file is part of the Leo library.
3
4// The Leo library is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// The Leo library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
16
17use serde::{Deserialize, Serialize};
18
19use std::fmt;
20
21/// The kind of a function definition.
22///
23/// - `Fn`: a regular function, callable from other Leo code.
24/// - `FinalFn`: a `final fn`, runs in the on-chain finalize context.
25/// - `EntryPoint`: a top-level program function — compiles to an Aleo
26///   `transition`. May or may not have a `final {}` block.
27/// - `Finalize`: the synthesized `final {}` block of an `EntryPoint`. Created
28///   during compilation, not written by the user.
29/// - `View`: a read-only `view fn` (V15). Top-level program component that
30///   reads finalize-store state and returns plaintext to external callers.
31///   Off-consensus, no transitions, no proofs, no state writes.
32#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq)]
33pub enum Variant {
34    #[default]
35    Fn,
36    FinalFn,
37    EntryPoint,
38    Finalize,
39    View,
40}
41
42impl Variant {
43    /// Returns true if the variant is an entry point.
44    pub fn is_entry(self) -> bool {
45        matches!(self, Variant::EntryPoint)
46    }
47
48    pub fn is_finalize(self) -> bool {
49        matches!(self, Variant::Finalize)
50    }
51
52    /// Returns true if the function accesses on-chain finalize-store state.
53    ///
54    /// This includes `final fn` and synthesized `finalize` (which write state) as well as
55    /// `view fn` (which read state). It is the right predicate for analyses that care about
56    /// on-chain state effects, regardless of whether the function runs as part of consensus.
57    pub fn is_onchain(self) -> bool {
58        matches!(self, Variant::Finalize | Variant::FinalFn | Variant::View)
59    }
60
61    /// Returns true if the function compiles to a `finalize` bytecode block (i.e. it runs
62    /// in the on-chain finalize runtime, not off-consensus).
63    ///
64    /// Use this predicate for analyses tied to finalize-runtime semantics: keeping
65    /// conditionals in bytecode, future-typed inputs, await tracking, and the
66    /// async-function assignment rules. Views are excluded because they compile to a
67    /// flat `function` block like transitions.
68    pub fn is_finalize_context(self) -> bool {
69        matches!(self, Variant::Finalize | Variant::FinalFn)
70    }
71
72    /// Returns true if the variant is a view function.
73    pub fn is_view(self) -> bool {
74        matches!(self, Variant::View)
75    }
76
77    /// Returns true if the variant is callable from outside the program
78    /// (transition entry point or view).
79    pub fn is_externally_callable(self) -> bool {
80        matches!(self, Variant::EntryPoint | Variant::View)
81    }
82}
83
84impl fmt::Display for Variant {
85    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
86        match self {
87            Self::FinalFn => write!(f, "final fn"),
88            Self::Fn => write!(f, "fn"),
89            Self::EntryPoint => write!(f, "entry"),
90            Self::Finalize => write!(f, "finalize"),
91            Self::View => write!(f, "view fn"),
92        }
93    }
94}