verbs_rs/agent/singleton_agent.rs
1//! Implementation of [AgentSet] for a single agent
2
3use crate::agent::traits::{Agent, AgentSet, RecordedAgent, RecordedAgentSet};
4use crate::contract::Transaction;
5use crate::env::{Env, Validator};
6use crate::DB;
7use alloy_primitives::Address;
8use rand::RngCore;
9use std::mem;
10
11/// Implementation of agent set for a single agent
12///
13/// Convenience implementation of the [AgentSet] trait
14/// for a set containing a single agent
15///
16/// # Examples
17///
18/// ```
19/// use rand::RngCore;
20/// use alloy_primitives::Address;
21/// use verbs_rs::{DB, env::{Env, Validator}};
22/// use verbs_rs::agent::{Agent, RecordedAgent, SingletonAgent, AgentSet};
23/// use verbs_rs::contract::Transaction;
24///
25/// struct DummyAgent{}
26///
27/// impl Agent for DummyAgent {
28/// fn update<D: DB, V: Validator, R: RngCore>(
29/// &mut self, rng: &mut R, network: &mut Env<D, V>
30/// ) -> Vec<Transaction> {
31/// Vec::default()
32/// }
33///
34/// fn get_address(&self) -> Address {
35/// Address::ZERO
36/// }
37/// }
38///
39/// impl RecordedAgent<bool> for DummyAgent {
40/// fn record<D: DB, V: Validator>(&mut self, _env: &mut Env<D, V>) -> bool {
41/// true
42/// }
43/// }
44///
45/// let singleton_agent = SingletonAgent::<bool, DummyAgent>::from(
46/// DummyAgent{}
47/// );
48///
49/// let addresses = singleton_agent.get_addresses();
50/// ```
51pub struct SingletonAgent<R, A: Agent + RecordedAgent<R>> {
52 /// Single agent in this set
53 agent: A,
54 /// Records of agent state over the course of the simulation.
55 records: Vec<R>,
56}
57
58impl<R, A: Agent + RecordedAgent<R>> SingletonAgent<R, A> {
59 /// Initialise an from an existing agents.
60 ///
61 /// # Arguments
62 ///
63 /// * `agent` - Agent controlled by the agent-set
64 ///
65 pub fn from(agent: A) -> Self {
66 SingletonAgent {
67 agent,
68 records: Vec::<R>::new(),
69 }
70 }
71 /// Get the recorded history of the agent.
72 pub fn get_records(&self) -> &Vec<R> {
73 &self.records
74 }
75
76 /// Take ownership of recorded data of the agent.
77 pub fn take_records(&mut self) -> Vec<R> {
78 mem::take(&mut self.records)
79 }
80}
81
82/// Implementations of agent updates and recording.
83impl<R: 'static, A: Agent + RecordedAgent<R> + 'static> AgentSet for SingletonAgent<R, A> {
84 /// Call the agent and optionally return EVM call
85 ///
86 /// This is called during the simulation, updating the state of
87 /// the agents, and collecting any submitted transactions into
88 /// a single vector.
89 ///
90 /// # Arguments
91 ///
92 /// * `rng` - Random generator
93 /// * `network` - Protocol deployment(s)
94 ///
95 fn call<D: DB, V: Validator, RG: RngCore>(
96 &mut self,
97 rng: &mut RG,
98 env: &mut Env<D, V>,
99 ) -> Vec<Transaction> {
100 self.agent.update(rng, env)
101 }
102 /// Record the current state of the agent
103 fn record<D: DB, V: Validator>(&mut self, env: &mut Env<D, V>) {
104 self.records.push(self.agent.record(env));
105 }
106 /// Get the address of the agent as a vector
107 fn get_addresses(&self) -> Vec<Address> {
108 vec![self.agent.get_address()]
109 }
110}
111
112impl<R, A: Agent + RecordedAgent<R>> RecordedAgentSet<R> for SingletonAgent<R, A> {
113 fn take_records(&mut self) -> Vec<Vec<R>> {
114 let x = mem::take(&mut self.records);
115 x.into_iter().map(|y| vec![y]).collect()
116 }
117}