From 2eaf96484f603c2b8b80033681df666a5efb4729 Mon Sep 17 00:00:00 2001 From: ryantaylor <2320507+ryantaylor@users.noreply.github.com> Date: Tue, 10 Mar 2026 14:30:25 -0400 Subject: [PATCH 1/5] Extract and expose battlegroup selection tick and AI takeover tick. --- src/player.rs | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/player.rs b/src/player.rs index aac43d6..0c46863 100644 --- a/src/player.rs +++ b/src/player.rs @@ -26,6 +26,8 @@ pub struct Player { faction: Faction, team: Team, battlegroup: Option, + battlegroup_selected_at: Option, + ai_takeover_at: Option, steam_id: Option, profile_id: Option, messages: Vec, @@ -60,6 +62,15 @@ impl Player { pub fn battlegroup(&self) -> Option { self.battlegroup } + /// The tick at which the player selected their battlegroup, or `None` if no battlegroup was selected. + pub fn battlegroup_selected_at(&self) -> Option { + self.battlegroup_selected_at + } + /// The tick at which the player dropped from the game and AI took over their army, or `None` if the + /// player never dropped from the game. + pub fn ai_takeover_at(&self) -> Option { + self.ai_takeover_at + } /// The Steam ID of the player, or `None` if the player is AI. This ID can be used to uniquely /// identify a player between replays, and connect them to their Steam profile. pub fn steam_id(&self) -> Option { @@ -146,6 +157,8 @@ pub(crate) fn player_from_data( .cloned() .unwrap_or_default(), battlegroup: None, + battlegroup_selected_at: None, + ai_takeover_at: None, }; if player.human { @@ -153,12 +166,25 @@ pub(crate) fn player_from_data( player.profile_id = Some(player_data.profile_id); } - player.battlegroup = match player + match player .commands .iter() .find(|&command| matches!(command, Command::SelectBattlegroup(_))) { - Some(Command::SelectBattlegroup(command)) => Some(command.pbgid()), + Some(Command::SelectBattlegroup(command)) => { + player.battlegroup = Some(command.pbgid()); + player.battlegroup_selected_at = Some(command.tick()); + }, + Some(_) => panic!(), + None => {}, + }; + + player.ai_takeover_at = match player + .commands + .iter() + .find(|&command| matches!(command, Command::AITakeover(_))) + { + Some(Command::AITakeover(command)) => Some(command.tick()), Some(_) => panic!(), None => None, }; From 119247e295ec4a626b72bb3b5baebce6752ad6bc Mon Sep 17 00:00:00 2001 From: ryantaylor <2320507+ryantaylor@users.noreply.github.com> Date: Tue, 10 Mar 2026 14:34:25 -0400 Subject: [PATCH 2/5] Formatting. --- src/player.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/player.rs b/src/player.rs index 0c46863..10c3d59 100644 --- a/src/player.rs +++ b/src/player.rs @@ -66,7 +66,7 @@ impl Player { pub fn battlegroup_selected_at(&self) -> Option { self.battlegroup_selected_at } - /// The tick at which the player dropped from the game and AI took over their army, or `None` if the + /// The tick at which the player dropped from the game and AI took over their army, or `None` if the /// player never dropped from the game. pub fn ai_takeover_at(&self) -> Option { self.ai_takeover_at @@ -174,9 +174,9 @@ pub(crate) fn player_from_data( Some(Command::SelectBattlegroup(command)) => { player.battlegroup = Some(command.pbgid()); player.battlegroup_selected_at = Some(command.tick()); - }, + } Some(_) => panic!(), - None => {}, + None => {} }; player.ai_takeover_at = match player From e44a19e5566c09a0a17a1fb1a24566a9ba65412a Mon Sep 17 00:00:00 2001 From: ryantaylor <2320507+ryantaylor@users.noreply.github.com> Date: Tue, 10 Mar 2026 14:35:54 -0400 Subject: [PATCH 3/5] Clippy lints. --- src/data/chunks/chunk.rs | 4 ++-- src/errors.rs | 1 - src/replay.rs | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/data/chunks/chunk.rs b/src/data/chunks/chunk.rs index 145bea9..a21808c 100644 --- a/src/data/chunks/chunk.rs +++ b/src/data/chunks/chunk.rs @@ -17,7 +17,7 @@ impl Chunk { move |input: Span| { let (input, header) = Header::parse(input)?; - return match &header.chunk_kind as &str { + match &header.chunk_kind as &str { "DATA" => match &header.chunk_type as &str { "AUTO" => DataAutoChunk::parse(input, header), "DATA" => DataDataChunk::parse(input, header), @@ -26,7 +26,7 @@ impl Chunk { }, "FOLD" => FoldChunk::parse(input, header, version), _ => panic!(), - }; + } } } } diff --git a/src/errors.rs b/src/errors.rs index cc62026..305bc97 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -6,5 +6,4 @@ use crate::data::Span; /// that is, the first failure point hit will exit with an error. This type returns an error that /// includes information on the segment of bytes being parsed and the location of the cursor at /// time of failure. - pub type ParseError<'a> = nom::Err>>; diff --git a/src/replay.rs b/src/replay.rs index f95b56b..72a983e 100644 --- a/src/replay.rs +++ b/src/replay.rs @@ -43,7 +43,7 @@ impl Replay { /// assert!(replay.is_ok()) /// } /// ``` - pub fn from_bytes(input: &[u8]) -> Result { + pub fn from_bytes(input: &[u8]) -> Result> { let info = TracableInfo::new().parser_width(64).fold("term"); let input: Span = LocatedSpan::new_extra(input, info); let (_, replay) = ReplayData::from_span(input)?; From 4820d07415079ee469c1399635a4975687b45d47 Mon Sep 17 00:00:00 2001 From: ryantaylor <2320507+ryantaylor@users.noreply.github.com> Date: Tue, 10 Mar 2026 14:46:06 -0400 Subject: [PATCH 4/5] Update MSRV to 1.71 to support new dependencies. --- .github/workflows/checks.yml | 8 ++++---- README.md | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index cc1f834..5b2980f 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -14,7 +14,7 @@ jobs: matrix: rust: - stable - - 1.66.0 + - 1.71.0 steps: - name: Checkout sources uses: actions/checkout@v2 @@ -38,7 +38,7 @@ jobs: matrix: rust: - stable - - 1.66.0 + - 1.71.0 steps: - name: Checkout sources uses: actions/checkout@v2 @@ -62,7 +62,7 @@ jobs: matrix: rust: - stable - - 1.66.0 + - 1.71.0 steps: - name: Checkout sources uses: actions/checkout@v2 @@ -89,7 +89,7 @@ jobs: matrix: rust: - stable - - 1.66.0 + - 1.71.0 steps: - name: Checkout sources uses: actions/checkout@v2 diff --git a/README.md b/README.md index 8b401fc..be8a069 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,7 @@ fn main() { # Compatibility -Official minimum supported Rust version is 1.65.0, because this is the version magnus requires. However, building without Ruby bindings should be fine on any compiler version that supports Rust 2021, though this isn't officially supported. +Official minimum supported Rust version is 1.71.0, to accomodate the MSRV of dependencies. Ruby bindings have some additional compatibility requirements, such as `libclang` and minimum Ruby version requirements. For more information see [magnus compatibility](https://github.com/matsadler/magnus#compatibility). From 3ce3aeaeb428f64cdc5c9875802540daf1669d61 Mon Sep 17 00:00:00 2001 From: ryantaylor <2320507+ryantaylor@users.noreply.github.com> Date: Tue, 10 Mar 2026 14:51:18 -0400 Subject: [PATCH 5/5] Only support stable officially to simplify testing. --- .github/workflows/checks.yml | 4 ---- README.md | 4 +++- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 5b2980f..ea928d1 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -14,7 +14,6 @@ jobs: matrix: rust: - stable - - 1.71.0 steps: - name: Checkout sources uses: actions/checkout@v2 @@ -38,7 +37,6 @@ jobs: matrix: rust: - stable - - 1.71.0 steps: - name: Checkout sources uses: actions/checkout@v2 @@ -62,7 +60,6 @@ jobs: matrix: rust: - stable - - 1.71.0 steps: - name: Checkout sources uses: actions/checkout@v2 @@ -89,7 +86,6 @@ jobs: matrix: rust: - stable - - 1.71.0 steps: - name: Checkout sources uses: actions/checkout@v2 diff --git a/README.md b/README.md index be8a069..bb8bff4 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,9 @@ fn main() { # Compatibility -Official minimum supported Rust version is 1.71.0, to accomodate the MSRV of dependencies. +`vault` is tested against stable Rust, and older versions aren't officially supported. However, you +should be able to compile on older versions, you just might have to pin dependencies to supported +versions. Ruby bindings have some additional compatibility requirements, such as `libclang` and minimum Ruby version requirements. For more information see [magnus compatibility](https://github.com/matsadler/magnus#compatibility).