/ console / program / src / data / future / find.rs
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  }