Skip to content

Commit

Permalink
Add Clientinfo.
Browse files Browse the repository at this point in the history
  • Loading branch information
vikpe committed May 2, 2024
1 parent a71acf8 commit c806a73
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 0 deletions.
23 changes: 23 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[package]
name = "quake_clientinfo"
description = "Parse QuakeWorld clientinfo strings."
categories = ["parsing"]
keywords = ["quake", "quakeworld"]
repository = "https://github.com/vikpe/quake_clientinfo"
authors = ["Viktor Persson <viktor.persson@arcsin.se>"]
version = "0.1.0"
edition = "2021"
license = "MIT"
include = [
"/Cargo.toml",
"/README.md",
"/src/**",
]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
quake_infostring = "0.1.0"

[dev-dependencies]
pretty_assertions = "1.4.0"
88 changes: 88 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
//! # quake_clientinfo
//! Parse QuakeWorld clientinfo strings
use std::collections::HashMap;

#[derive(Debug, Default, Eq, PartialEq)]
pub struct Clientinfo {
pub name: Option<String>,
pub team: Option<String>,
pub topcolor: Option<i32>,
pub bottomcolor: Option<i32>,
pub spectator: Option<i32>,
pub client: Option<String>,
}

impl From<&HashMap<String, String>> for Clientinfo {
fn from(value: &HashMap<String, String>) -> Self {
Self {
client: map_get_string(value, "*client"),
name: map_get_string(value, "name"),
team: map_get_string(value, "team"),
topcolor: map_get_int(value, "topcolor"),
bottomcolor: map_get_int(value, "bottomcolor"),
spectator: map_get_int(value, "*spectator"),
}
}
}

fn map_get_string(map: &HashMap<String, String>, key: &str) -> Option<String> {
map.get(key).map(|v| v.to_string())
}

fn map_get_int(map: &HashMap<String, String>, key: &str) -> Option<i32> {
map.get(key)?.parse().ok()
}

/// # Examples
/// ```
/// use quake_clientinfo::Clientinfo;
///
/// let info = Clientinfo::from(r#"\team\red\name\Alpha\*spectator\1"#);
/// assert_eq!(info.name, Some("Alpha".to_string()));
/// assert_eq!(info.team, Some("red".to_string()));
/// assert_eq!(info.spectator, Some(1));
/// assert_eq!(info.topcolor, None);
/// ```
impl From<&str> for Clientinfo {
fn from(value: &str) -> Self {
Self::from(&quake_infostring::to_hashmap(value))
}
}

#[cfg(test)]
mod tests {
use pretty_assertions::assert_eq;

use super::*;

const INFO_STR: &str =
r#"\*client\libqwclient 0.1\*spectator\1\bottomcolor\11\topcolor\12\team\red\name\Alpha"#;

#[test]
fn test_from_str() {
let info = Clientinfo::from(INFO_STR);
assert_eq!(info.name, Some("Alpha".to_string()));
assert_eq!(info.team, Some("red".to_string()));
assert_eq!(info.topcolor, Some(12));
assert_eq!(info.bottomcolor, Some(11));
assert_eq!(info.spectator, Some(1));
assert_eq!(info.client, Some("libqwclient 0.1".to_string()));
}

#[test]
fn test_from_hashmap() {
let map = HashMap::from([
("name".to_string(), "Alpha".to_string()),
("team".to_string(), "red".to_string()),
]);

let expected = Clientinfo {
name: Some("Alpha".to_string()),
team: Some("red".to_string()),
..Default::default()
};

assert_eq!(Clientinfo::from(&map), expected);
}
}

0 comments on commit c806a73

Please sign in to comment.