use crate::agent::traits::{Agent, AgentSet, RecordedAgent, RecordedAgentSet};
use crate::contract::Transaction;
use crate::env::{Env, Validator};
use crate::DB;
use alloy_primitives::Address;
use rand::RngCore;
use std::mem;
pub struct SingletonAgent<R, A: Agent + RecordedAgent<R>> {
agent: A,
records: Vec<R>,
}
impl<R, A: Agent + RecordedAgent<R>> SingletonAgent<R, A> {
pub fn from(agent: A) -> Self {
SingletonAgent {
agent,
records: Vec::<R>::new(),
}
}
pub fn get_records(&self) -> &Vec<R> {
&self.records
}
pub fn take_records(&mut self) -> Vec<R> {
mem::take(&mut self.records)
}
}
impl<R: 'static, A: Agent + RecordedAgent<R> + 'static> AgentSet for SingletonAgent<R, A> {
fn call<D: DB, V: Validator, RG: RngCore>(
&mut self,
rng: &mut RG,
env: &mut Env<D, V>,
) -> Vec<Transaction> {
self.agent.update(rng, env)
}
fn record<D: DB, V: Validator>(&mut self, env: &mut Env<D, V>) {
self.records.push(self.agent.record(env));
}
fn get_addresses(&self) -> Vec<Address> {
vec![self.agent.get_address()]
}
}
impl<R, A: Agent + RecordedAgent<R>> RecordedAgentSet<R> for SingletonAgent<R, A> {
fn take_records(&mut self) -> Vec<Vec<R>> {
let x = mem::take(&mut self.records);
x.into_iter().map(|y| vec![y]).collect()
}
}