initial commit

This commit is contained in:
Niklas Kapelle 2025-02-21 20:17:40 +01:00
commit a1a5923f79
Signed by: niklas
GPG Key ID: 4EB651B36D841D16
7 changed files with 555 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

392
Cargo.lock generated Normal file
View File

@ -0,0 +1,392 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "android-tzdata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]]
name = "autocfg"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "beerpong"
version = "0.1.0"
dependencies = [
"chrono",
"regex",
"serde",
"serde_json",
]
[[package]]
name = "bumpalo"
version = "3.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
[[package]]
name = "cc"
version = "1.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e80e3b6a3ab07840e1cae9b0666a63970dc28e8ed5ffbcdacbfc760c281bfc1"
dependencies = [
"shlex",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
dependencies = [
"android-tzdata",
"iana-time-zone",
"js-sys",
"num-traits",
"serde",
"wasm-bindgen",
"windows-targets",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "iana-time-zone"
version = "0.1.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]]
name = "itoa"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
[[package]]
name = "js-sys"
version = "0.3.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0cb94a0ffd3f3ee755c20f7d8752f45cac88605a4dcf808abcff72873296ec7b"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "libc"
version = "0.2.158"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
[[package]]
name = "log"
version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
[[package]]
name = "proc-macro2"
version = "1.0.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
dependencies = [
"proc-macro2",
]
[[package]]
name = "regex"
version = "1.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
[[package]]
name = "ryu"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
[[package]]
name = "serde"
version = "1.0.210"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.210"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.128"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8"
dependencies = [
"itoa",
"memchr",
"ryu",
"serde",
]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "syn"
version = "2.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
[[package]]
name = "wasm-bindgen"
version = "0.2.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef073ced962d62984fb38a36e5fdc1a2b23c9e0e1fa0689bb97afa4202ef6887"
dependencies = [
"cfg-if",
"once_cell",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4bfab14ef75323f4eb75fa52ee0a3fb59611977fd3240da19b2cf36ff85030e"
dependencies = [
"bumpalo",
"log",
"once_cell",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7bec9830f60924d9ceb3ef99d55c155be8afa76954edffbb5936ff4509474e7"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c74f6e152a76a2ad448e223b0fc0b6b5747649c3d769cc6bf45737bf97d0ed6"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a42f6c679374623f295a8623adfe63d9284091245c3504bde47c17a3ce2777d9"
[[package]]
name = "windows-core"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"

10
Cargo.toml Normal file
View File

@ -0,0 +1,10 @@
[package]
name = "beerpong"
version = "0.1.0"
edition = "2021"
[dependencies]
chrono = { version = "0.4.38", features = ["serde"] }
regex = "1.10.6"
serde = { version = "1.0.210", features = ["derive"]}
serde_json = "1.0.128"

23
src/game.rs Normal file
View File

@ -0,0 +1,23 @@
use std::fmt::Display;
use chrono::{DateTime, FixedOffset, Local, Utc};
use serde::{Serialize, Serializer};
#[derive(Serialize)]
pub struct Game{
pub added: DateTime<FixedOffset>,
pub author: String,
pub t0p0: String,
pub t0p1: String,
pub t1p0: String,
pub t1p1: String,
pub score: i8,
pub ot: bool,
}
impl Display for Game {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f,"{} {}: {} + {} ({}) {} + {} {}",self.added.to_string(),self.author,self.t0p0,self.t0p0,self.score,self.t1p0,self.t1p1,if self.ot { "(OT)" } else { ""})
}
}

10
src/main.rs Normal file
View File

@ -0,0 +1,10 @@
mod game;
mod names;
mod raw_parser;
fn main() {
let games = raw_parser::parse_file("./data/chat.txt").unwrap();
let json = serde_json::to_string(&games).unwrap();
println!("{}",json);
}

52
src/names.rs Normal file
View File

@ -0,0 +1,52 @@
pub fn normalize_name(name: &str) -> Option<String> {
let lower_name = name.to_lowercase();
let rtn = match lower_name.as_str(){
"niklas" | "niklas kapelle" => "niklas",
"kilian" | "kili" => "kilian",
"luca" | "luca göttle" => "luca",
"line" | "line frische" => "line",
"simon" | "simon müller" => "simon",
"tim" | "tim waldherr" => "tim",
"manu" | "manuel kraiss" | "manuel"=> "manu",
"vivi" | "vivien" | "vivien (simon)" => "vivien",
"mika" | "mika wielsch" => "mika",
"kathi" => "kathi",
"guido" => "guido",
"tanita" => "tanita",
"elias" => "elias",
"moritz" | "moritz hübner" | "morirz" | "moritz huebner" => "moritz",
"liz" => "liz",
"adi" | "adrian" => "adi",
"fabi" => "fabi",
"bühl" | "felix" => "bühl",
"benni" | "benjamin passow" => "benni",
"maike" => "maike",
"aliern" => "aliern",
"jasmina" => "jasmina",
"alisa" | "alissa" => "alisa",
"linda" => "linda",
"judi" => "judi",
"hannah" => "hannah",
"elena" => "elena",
"sina" => "sina",
"mario" | "pablo" | "p4blo" | "mario lopez" => "mario",
"julian" => "julian",
"siggi" => "siggi",
"elisa" | "eli" | "elli" => "elisa",
"marvin" | "marvin göttle" => "marvin",
"aileen" | "eileen" => "aileen",
"murillo" => "murillo",
"will" => "will",
"muriel" => "muriel",
"leslie" => "leslie",
"ina" => "ina",
"kim" => "kim",
"naomi" => "naomi",
_=> {
return None;
}
};
Some(rtn.to_string())
}

67
src/raw_parser.rs Normal file
View File

@ -0,0 +1,67 @@
use std::{error::Error, fs::read_to_string};
use chrono::{FixedOffset, NaiveDateTime, TimeZone};
use regex::Regex;
use crate::game::Game;
use super::names::normalize_name;
pub fn parse_file(file: &str) -> Result<Vec<Game>, Box<dyn Error>> {
let file = read_to_string(file)?;
let games = file.lines().map(parse_line);
games.clone().for_each(|e| {
if let Err(err) = e { eprintln!("{}",err) }
});
Ok(games.flatten().collect())
}
fn parse_line(line: &str) -> Result<Game,Box<dyn Error>>{
let regex = Regex::new(r"(?m)^(\d+/\d+/\d+, \d+:\d+) - (.*): (.*)\+(.*) (\d)\s*[-:]\s*(\d) (.*)\+(.*?)(\s*\(?OT\)?)?\s*$")?;
let Some(caps) = regex.captures(line) else {
return Err(format!("Failed to match regex: {}",line).into());
};
let capture_groups: Vec<String> = caps
.iter()
.skip(1)
.flatten()
.map(|cap| cap.as_str().to_string())
.collect();
let date_time = NaiveDateTime::parse_from_str(capture_groups.first().unwrap().trim(), "%m/%d/%y, %H:%M")?;
let fixed_offset = FixedOffset::east_opt(2 * 3600).expect("Invalid timezone offset");
let author = capture_groups.get(1).unwrap().trim();
let t1_0 = capture_groups.get(2).unwrap().trim();
let t1_1 = capture_groups.get(3).unwrap().trim();
let cups_t1: i8 = capture_groups.get(4).unwrap().parse()?;
let cups_t2: i8 = capture_groups.get(5).unwrap().parse()?;
let t2_0 = capture_groups.get(6).unwrap().trim();
let t2_1 = capture_groups.get(7).unwrap().trim();
let is_ot = capture_groups.get(8).is_some();
let norm_t1_0 = normalize_name(t1_0).ok_or_else(|| format!("Unknown name: {} on line {}",t1_0,line))?;
let norm_t1_1 = normalize_name(t1_1).ok_or_else(|| format!("Unknown name: {} on line {}",t1_1,line))?;
let norm_t2_0 = normalize_name(t2_0).ok_or_else(|| format!("Unknown name: {} on line {}",t2_0,line))?;
let norm_t2_1 = normalize_name(t2_1).ok_or_else(|| format!("Unknown name: {} on line {}",t2_1,line))?;
let norm_author = normalize_name(author).unwrap_or_else(|| "unknown".to_string());
Ok(Game{
added: fixed_offset.from_utc_datetime(&date_time),
author: norm_author,
t0p0: norm_t1_0,
t0p1: norm_t1_1,
t1p0: norm_t2_0,
t1p1: norm_t2_1,
score: cups_t1 - cups_t2,
ot: is_ot,
})
}