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
// 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/>. use crate::PositiveNumber; use leo_input::types::ArrayDimensions as InputArrayDimensions; use serde::{Deserialize, Serialize}; use std::fmt; /// A vector of positive numbers that represent array dimensions. /// Can be used in an array [`Type`] or an array initializer [`Expression`]. #[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, Default, Hash)] pub struct ArrayDimensions(pub Vec<PositiveNumber>); impl ArrayDimensions { /// /// Appends a vector of array dimensions to the self array dimensions. /// pub fn append(&mut self, other: &mut ArrayDimensions) { self.0.append(&mut other.0) } /// /// Returns the array dimensions as strings. /// pub fn to_strings(&self) -> Vec<String> { self.0.iter().map(|number| number.to_string()).collect() } /// /// Returns `true` if the all array dimensions have been removed. /// /// This method is called after repeated calls to `remove_first`. /// pub fn is_empty(&self) -> bool { self.0.is_empty() } /// /// Returns `true` if there is an array dimension equal to zero. /// pub fn is_zero(&self) -> bool { self.0.iter().any(|number| number.is_zero()) } /// /// Returns the first dimension of the array. /// pub fn first(&self) -> Option<&PositiveNumber> { self.0.first() } /// /// Attempts to remove the first dimension from the array. /// /// If the first dimension exists, then remove and return `Some(PositiveNumber)`. /// If the first dimension does not exist, then return `None`. /// pub fn remove_first(&mut self) -> Option<PositiveNumber> { // If there are no dimensions in the array, then return None. self.0.first()?; // Remove the first dimension. let removed = self.0.remove(0); // Return the first dimension. Some(removed) } /// /// Attempts to remove the last dimension from the array. /// /// If the last dimension exists, then remove and return `Some(PositiveNumber)`. /// If the last dimension does not exist, then return `None`. /// pub fn remove_last(&mut self) -> Option<PositiveNumber> { self.0.pop() } } /// Create a new [`ArrayDimensions`] from a [`InputArrayDimensions`] in a Leo program file. impl<'ast> From<InputArrayDimensions<'ast>> for ArrayDimensions { fn from(dimensions: InputArrayDimensions<'ast>) -> Self { Self(match dimensions { InputArrayDimensions::Single(single) => vec![PositiveNumber::from(single.number)], InputArrayDimensions::Multiple(multiple) => { multiple.numbers.into_iter().map(PositiveNumber::from).collect() } }) } } impl fmt::Display for ArrayDimensions { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if self.0.len() == 1 { // Write dimensions without parenthesis. write!(f, "{}", self.0[0]) } else { // Write dimensions with parenthesis. let dimensions = self.0.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(", "); write!(f, "({})", dimensions) } } }