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
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Copyright (C) 2019-2021 Aleo Systems Inc.
// This file is part of the Leo library.

// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.

/// Constructs an input section to store data parsed from a Leo input file.
/// Constructs sections that pass variables to the main function through the input keyword.
#[macro_export]
macro_rules! record_input_section {
    ($($name: ident), *) => ($(

        /// An input section declared in an input file with `[$name]`.
        #[derive(Clone, PartialEq, Eq, Default)]
        pub struct $name {
            is_present: bool,
            values: IndexMap<Parameter, Option<InputValue>>,
        }

        impl $name {
            pub fn new() -> Self {
                Self::default()
            }

            /// Returns an empty version of this struct with `None` values.
            /// Called during constraint synthesis to provide private input variables.
            pub fn empty(&self) -> Self {
                let is_present = self.is_present;
                let mut values = self.values.clone();

                values.iter_mut().for_each(|(_parameter, value)| {
                    *value = None;
                });

                Self { is_present, values }
            }

            /// Returns `true` if the main function contains the `$name` variable.
            pub fn is_present(&self) -> bool {
                self.is_present
            }

            /// Parses register input definitions and stores them in `self`.
            /// This function is called if the main function input contains the `$name` variable.
            pub fn parse(&mut self, definitions: Vec<Definition>) -> Result<(), InputParserError> {
                self.is_present = true;

                for definition in definitions {
                    let value = InputValue::from_expression(definition.parameter.type_.clone(), definition.expression)?;
                    let parameter = Parameter::from(definition.parameter);

                    self.values.insert(parameter, Some(value));
                }

                Ok(())
            }

            /// Returns this section's [IndexMap] of values.
            pub fn values(&self) -> IndexMap<Parameter, Option<InputValue>> {
                self.values.clone()
            }
        }
    )*)
}

/// Constructs an input section to store data parsed from a Leo input file.
/// Constructs sections that pass variables directly to the main function.
#[macro_export]
macro_rules! main_input_section {
    ($($name: ident), *) => ($(

        /// `[$name]` program input section.
        #[derive(Clone, PartialEq, Eq, Default)]
        pub struct $name {
            input: IndexMap<String, Option<InputValue>>,
        }

        #[allow(clippy::len_without_is_empty)]
        impl $name {
            pub fn new() -> Self {
                Self::default()
            }

            /// Returns an empty version of this struct with `None` values.
            /// Called during constraint synthesis to provide private input variables.
            pub fn empty(&self) -> Self {
                let mut input = self.input.clone();

                input.iter_mut().for_each(|(_name, value)| {
                    *value = None;
                });

                Self { input }
            }

            pub fn len(&self) -> usize {
                self.input.len()
            }

            pub fn insert(&mut self, key: String, value: Option<InputValue>) {
                self.input.insert(key, value);
            }

            /// Parses main input definitions and stores them in `self`.
            pub fn parse(&mut self, definitions: Vec<Definition>) -> Result<(), InputParserError> {
                for definition in definitions {
                    let name = definition.parameter.variable.value;
                    let value = InputValue::from_expression(definition.parameter.type_, definition.expression)?;

                    self.insert(name, Some(value));
                }

                Ok(())
            }

            /// Returns an `Option` of the main function input at `name`.
            pub fn get(&self, name: &str) -> Option<Option<InputValue>> {
                self.input.get(name).cloned()
            }
        }
    )*)
}