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}