find.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 21 impl<N: Network> Future<N> { 22 /// Returns a value from the given path. 23 pub fn find<A: Into<Access<N>> + Copy + Debug>(&self, path: &[A]) -> Result<Value<N>> { 24 // Ensure the path is not empty. 25 ensure!(!path.is_empty(), "Attempted to find an argument with an empty path."); 26 27 // A helper enum to track the the argument. 28 enum ArgumentRefType<'a, N: Network> { 29 /// A plaintext type. 30 Plaintext(&'a Plaintext<N>), 31 /// A future. 32 Future(&'a Future<N>), 33 } 34 35 // Initialize a value starting from the top-level. 36 let mut value = ArgumentRefType::Future(self); 37 38 // Iterate through the path to retrieve the value. 39 for access in path.iter() { 40 let access = (*access).into(); 41 match (value, access) { 42 (ArgumentRefType::Plaintext(Plaintext::Struct(members, ..)), Access::Member(identifier)) => { 43 match members.get(&identifier) { 44 // Retrieve the member and update `value` for the next iteration. 45 Some(member) => value = ArgumentRefType::Plaintext(member), 46 // Halts if the member does not exist. 47 None => bail!("Failed to locate member '{identifier}'"), 48 } 49 } 50 (ArgumentRefType::Plaintext(Plaintext::Array(array, ..)), Access::Index(index)) => { 51 match array.get(*index as usize) { 52 // Retrieve the element and update `value` for the next iteration. 53 Some(element) => value = ArgumentRefType::Plaintext(element), 54 // Halts if the index is out of bounds. 55 None => bail!("Index '{index}' is out of bounds"), 56 } 57 } 58 (ArgumentRefType::Future(future), Access::Index(index)) => { 59 match future.arguments.get(*index as usize) { 60 // If the argument is a future, update `value` for the next iteration. 61 Some(Argument::Future(future)) => value = ArgumentRefType::Future(future), 62 // If the argument is a plaintext, update `value` for the next iteration. 63 Some(Argument::Plaintext(plaintext)) => value = ArgumentRefType::Plaintext(plaintext), 64 // Halts if the index is out of bounds. 65 None => bail!("Index '{index}' is out of bounds"), 66 } 67 } 68 _ => bail!("Invalid access `{access}`"), 69 } 70 } 71 72 match value { 73 ArgumentRefType::Plaintext(plaintext) => Ok(Value::Plaintext(plaintext.clone())), 74 ArgumentRefType::Future(future) => Ok(Value::Future(future.clone())), 75 } 76 } 77 }