diff options
-rw-r--r-- | src/lib.rs | 61 |
1 files changed, 53 insertions, 8 deletions
@@ -1,3 +1,5 @@ +//! `evtclib` is a crate aiming to provide utility functions to parse and work +//! with `.evtc` reports generated by arcdps. #![feature(try_trait)] #[macro_use] extern crate quick_error; @@ -11,6 +13,21 @@ pub mod raw; mod event; pub use event::{Event, EventKind}; +/// A macro that returns `true` when the given expression matches the pattern. +/// +/// ```rust +/// assert!(matches!(Some(4), Some(_))); +/// assert!(!matches!(Some(2), None)); +/// ``` +macro_rules! matches { + ($expression:expr, $($pattern:pat)|*) => ( + match $expression { + $($pattern)|+ => true, + _ => false, + } + ) +} + quick_error! { #[derive(Debug)] pub enum EvtcError { @@ -65,25 +82,53 @@ pub struct Agent { #[derive(Debug, Clone)] pub struct Log { agents: Vec<Agent>, + events: Vec<Event>, +} + +impl Log { + /// Return all agents present in this log. + pub fn agents(&self) -> &[Agent] { + &self.agents + } + + /// Return an agent based on its address. + pub fn agent_by_addr(&self, addr: u64) -> Option<&Agent> { + self.agents.iter().find(|a| a.addr == addr) + } + + /// Return an agent based on the instance ID. + pub fn agent_by_instance_id(&self, instance_id: u16) -> Option<&Agent> { + self.agents.iter().find(|a| a.instance_id == instance_id) + } + + /// Return an iterator over all agents that represent player characters. + pub fn players(&self) -> impl Iterator<Item=&Agent> { + self.agents.iter().filter(|a| matches!(a.kind, AgentKind::Player { .. })) + } + + /// Return an iterator over all agents that are NPCs. + pub fn npcs(&self) -> impl Iterator<Item=&Agent> { + self.agents.iter().filter(|a| matches!(a.kind, AgentKind::Character(_))) + } + + /// Return all events present in this log. + pub fn events(&self) -> &[Event] { + &self.events + } } pub fn process(data: &raw::Evtc) -> Result<Log, EvtcError> { // Prepare "augmented" agents - let mut agents = setup_agents(data)?; - + let mut agents = setup_agents(data)?; // Do the first aware/last aware field set_agent_awares(data, &mut agents)?; // Set the master addr field set_agent_masters(data, &mut agents)?; - for agent in &agents { - if let AgentKind::Player { .. } = agent.kind { - println!("Agent: {:#?}", agent); - } - } + let events = data.events.iter().filter_map(Event::from_raw).collect(); - panic!(); + Ok(Log { agents, events }) } fn setup_agents(data: &raw::Evtc) -> Result<Vec<Agent>, EvtcError> { |