parse.rs
1 // Copyright (c) 2025-2026 ACDC Network 2 // This file is part of the alphavm library. 3 // 4 // Alpha Chain | Delta Chain Protocol 5 // International Monetary Graphite. 6 // 7 // Derived from Aleo (https://aleo.org) and ProvableHQ (https://provable.com). 8 // They built world-class ZK infrastructure. We installed the EASY button. 9 // Their cryptography: elegant. Our modifications: bureaucracy-compatible. 10 // Original brilliance: theirs. Robert's Rules: ours. Bugs: definitely ours. 11 // 12 // Original Aleo/ProvableHQ code subject to Apache 2.0 https://www.apache.org/licenses/LICENSE-2.0 13 // All modifications and new work: CC0 1.0 Universal Public Domain Dedication. 14 // No rights reserved. No permission required. No warranty. No refunds. 15 // 16 // https://creativecommons.org/publicdomain/zero/1.0/ 17 // SPDX-License-Identifier: CC0-1.0 18 19 use super::*; 20 use crate::{Identifier, LiteralType}; 21 22 impl<N: Network> Parser for ArrayType<N> { 23 /// Parses a string into a literal type. 24 #[inline] 25 fn parse(string: &str) -> ParserResult<'_, Self> { 26 // A helper function to parse the innermost element type. 27 fn parse_inner_element_type<N: Network>(string: &str) -> ParserResult<'_, PlaintextType<N>> { 28 alt((map(LiteralType::parse, PlaintextType::from), map(Identifier::parse, PlaintextType::from)))(string) 29 } 30 31 // A helper function to parse the length of each dimension. 32 fn parse_length<N: Network>(string: &str) -> ParserResult<'_, U32<N>> { 33 // Parse the whitespaces from the string. 34 let (string, _) = Sanitizer::parse_whitespaces(string)?; 35 // Parse the semicolon from the string. 36 let (string, _) = tag(";")(string)?; 37 // Parse the whitespaces from the string. 38 let (string, _) = Sanitizer::parse_whitespaces(string)?; 39 // Parse the length. 40 let (string, length) = U32::parse(string)?; 41 // Parse the whitespaces from the string. 42 let (string, _) = Sanitizer::parse_whitespaces(string)?; 43 // Parse the closing bracket. 44 let (string, _) = tag("]")(string)?; 45 // Return the length. 46 Ok((string, length)) 47 } 48 49 // Parse the opening brackets and validate the number of dimensions. 50 let (string, dimensions) = map_res(many0_count(pair(tag("["), Sanitizer::parse_whitespaces)), |dimensions| { 51 if dimensions.is_zero() { 52 Err("An array must have at least one dimension.".to_string()) 53 } else if dimensions > N::MAX_DATA_DEPTH { 54 Err(format!("Array type exceeds the maximum depth of {}.", N::MAX_DATA_DEPTH)) 55 } else { 56 Ok(dimensions) 57 } 58 })(string)?; 59 60 // Parse the whitespaces from the string. 61 let (string, _) = Sanitizer::parse_whitespaces(string)?; 62 // Parse the innermost element type and the dimensions and return the array type. 63 map_res(pair(parse_inner_element_type, count(parse_length, dimensions)), |(plaintext_type, mut dimensions)| { 64 // Reverse the dimensions, since they were parsed from innermost to outermost. 65 dimensions.reverse(); 66 ArrayType::new(plaintext_type, dimensions) 67 })(string) 68 } 69 } 70 71 impl<N: Network> FromStr for ArrayType<N> { 72 type Err = Error; 73 74 /// Returns an array type from a string literal. 75 fn from_str(string: &str) -> Result<Self> { 76 match Self::parse(string) { 77 Ok((remainder, object)) => { 78 // Ensure the remainder is empty. 79 ensure!(remainder.is_empty(), "Failed to parse string. Found invalid character in: \"{remainder}\""); 80 // Return the object. 81 Ok(object) 82 } 83 Err(error) => bail!("Failed to parse string. {error}"), 84 } 85 } 86 } 87 88 impl<N: Network> Debug for ArrayType<N> { 89 /// Prints the array type as a string. 90 fn fmt(&self, f: &mut Formatter) -> fmt::Result { 91 Display::fmt(self, f) 92 } 93 } 94 95 impl<N: Network> Display for ArrayType<N> { 96 /// Prints the array type as a string. 97 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 98 write!(f, "[{}; {}]", self.next_element_type(), self.length()) 99 } 100 }