diff options
Diffstat (limited to 'planetwars-matchrunner/src/match_log.rs')
-rw-r--r-- | planetwars-matchrunner/src/match_log.rs | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/planetwars-matchrunner/src/match_log.rs b/planetwars-matchrunner/src/match_log.rs new file mode 100644 index 0000000..9991f99 --- /dev/null +++ b/planetwars-matchrunner/src/match_log.rs @@ -0,0 +1,45 @@ +use std::path::Path; + +use serde::{Deserialize, Serialize}; +use tokio::{fs::File, io::AsyncWriteExt}; + +use planetwars_rules::protocol::State; +use tokio::sync::mpsc; + +#[derive(Serialize, Deserialize, Debug)] +#[serde(tag = "type")] +pub enum MatchLogMessage { + #[serde(rename = "gamestate")] + GameState(State), + #[serde(rename = "stderr")] + StdErr(StdErrMessage), +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct StdErrMessage { + pub player_id: u32, + pub message: String, +} + +pub type MatchLogger = mpsc::UnboundedSender<MatchLogMessage>; + +pub async fn create_log_sink(log_file_path: &Path) -> MatchLogger { + let (tx, rx) = mpsc::unbounded_channel(); + let log_file = File::create(log_file_path) + .await + .expect("Could not create log file"); + tokio::spawn(run_log_sink(rx, log_file)); + return tx; +} + +async fn run_log_sink(mut rx: mpsc::UnboundedReceiver<MatchLogMessage>, mut file: File) { + while let Some(message) = rx.recv().await { + let json = serde_json::to_string(&message).expect("failed to serialize message"); + file.write_all(json.as_bytes()) + .await + .expect("failed to write log message to file"); + file.write_all(b"\n") + .await + .expect("failed to write newline log message to file"); + } +} |