find.rs
1 // Copyright (c) 2019-2025 Alpha-Delta Network Inc. 2 // This file is part of the alphavm library. 3 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at: 7 8 // http://www.apache.org/licenses/LICENSE-2.0 9 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 use super::*; 17 18 impl<N: Network> Plaintext<N> { 19 /// Returns the plaintext member from the given path. 20 pub fn find<A: Into<Access<N>> + Copy + Debug>(&self, path: &[A]) -> Result<Plaintext<N>> { 21 // Ensure the path is not empty. 22 ensure!(!path.is_empty(), "Attempted to find a member with an empty path."); 23 24 match self { 25 // Halts if the value is not a struct. 26 Self::Literal(..) => bail!("'{self}' is not a struct"), 27 // Retrieve the value of the member (from the value). 28 Self::Struct(..) | Self::Array(..) => { 29 // Initialize the plaintext starting from the top-level. 30 let mut plaintext = self; 31 32 // Iterate through the path to retrieve the value. 33 for access in path.iter() { 34 let access = (*access).into(); 35 match (plaintext, access) { 36 (Self::Struct(members, ..), Access::Member(identifier)) => { 37 match members.get(&identifier) { 38 // Retrieve the member and update `plaintext` for the next iteration. 39 Some(member) => plaintext = member, 40 // Halts if the member does not exist. 41 None => bail!("Failed to locate member '{identifier}' in '{self}'"), 42 } 43 } 44 (Self::Array(array, ..), Access::Index(index)) => { 45 match array.get(*index as usize) { 46 // Retrieve the element and update `plaintext` for the next iteration. 47 Some(element) => plaintext = element, 48 // Halts if the index is out of bounds. 49 None => bail!("Index '{index}' for '{self}' is out of bounds"), 50 } 51 } 52 _ => bail!("Invalid access `{access}` for `{plaintext}`"), 53 } 54 } 55 56 // Return the output. 57 Ok(plaintext.clone()) 58 } 59 } 60 } 61 }