evtc_parse/
log.rs
1use crate::{util::Endian, Agent, Header, LogTransformed, Parse, ParseError, Save, Skill};
2use byteorder::{ReadBytesExt, WriteBytesExt};
3use evtc::Event;
4use std::{fs::File, io, path::Path};
5
6#[cfg(feature = "serde")]
7use serde::{Deserialize, Serialize};
8
9#[derive(Debug, Clone)]
11#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
12pub struct Log {
13 pub header: Header,
15
16 pub agents: Vec<Agent>,
18
19 pub skills: Vec<Skill>,
21
22 pub events: Vec<Event>,
26}
27
28impl Log {
29 pub fn parse_file(path: impl AsRef<Path>) -> Result<Log, ParseError> {
33 let path = path.as_ref();
34 let mut file = io::BufReader::new(File::open(path)?);
35
36 #[cfg(feature = "zevtc")]
37 if let Some("zevtc" | "zip") = path.extension().and_then(|ext| ext.to_str()) {
38 return Self::parse_zevtc(file);
39 }
40
41 Log::parse(&mut file)
42 }
43
44 #[inline]
46 pub fn agent(&self, id: u64) -> Option<&Agent> {
47 self.agents.iter().find(|agent| agent.id == id)
48 }
49
50 #[inline]
52 pub fn agent_mut(&mut self, id: u64) -> Option<&mut Agent> {
53 self.agents.iter_mut().find(|agent| agent.id == id)
54 }
55
56 #[inline]
58 pub fn agent_name(&self, id: u64) -> Option<&[String]> {
59 self.agent(id).map(|agent| agent.name.as_slice())
60 }
61
62 #[inline]
64 pub fn skill(&self, id: u32) -> Option<&Skill> {
65 self.skills.iter().find(|skill| skill.id == id)
66 }
67
68 #[inline]
70 pub fn skill_mut(&mut self, id: u32) -> Option<&mut Skill> {
71 self.skills.iter_mut().find(|skill| skill.id == id)
72 }
73
74 #[inline]
76 pub fn skill_name(&self, id: u32) -> Option<&str> {
77 self.skill(id).map(|skill| skill.name.as_str())
78 }
79
80 #[inline]
82 pub fn into_transformed(self) -> LogTransformed {
83 self.into()
84 }
85}
86
87impl Parse for Log {
88 type Error = ParseError;
89
90 fn parse(input: &mut impl io::Read) -> Result<Self, Self::Error> {
91 let header = Header::parse(input)?;
92
93 if header.revision != 1 {
95 return Err(ParseError::UnsupportedRevision(header.revision));
96 }
97
98 let agent_count = input.read_u32::<Endian>()?;
99 let agents = Agent::parse_multi(input, agent_count as usize)?;
100
101 let skill_count = input.read_u32::<Endian>()?;
102 let skills = Skill::parse_multi(input, skill_count as usize)?;
103
104 let mut events = Vec::new();
105 while let Ok(event) = Event::parse(input) {
106 events.push(event);
107 }
108
109 Ok(Self {
110 header,
111 agents,
112 skills,
113 events,
114 })
115 }
116}
117
118impl Save for Log {
119 type Error = io::Error;
120
121 fn save(&self, output: &mut impl io::Write) -> Result<(), Self::Error> {
122 self.header.save(output)?;
123
124 output.write_u32::<Endian>(self.agents.len() as u32)?;
125 for agent in &self.agents {
126 agent.save(output)?;
127 }
128
129 output.write_u32::<Endian>(self.skills.len() as u32)?;
130 for skill in &self.skills {
131 skill.save(output)?;
132 }
133
134 for event in &self.events {
135 event.save(output)?;
136 }
137
138 Ok(())
139 }
140}