initial commit

This commit is contained in:
2025-03-11 14:50:59 +01:00
commit 9d1a79d6f5
6 changed files with 9867 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target

70
Cargo.lock generated Normal file
View File

@@ -0,0 +1,70 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "ircp2000"
version = "0.1.0"
dependencies = [
"phf",
"phf_codegen",
]
[[package]]
name = "phf"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
dependencies = [
"phf_shared",
]
[[package]]
name = "phf_codegen"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a"
dependencies = [
"phf_generator",
"phf_shared",
]
[[package]]
name = "phf_generator"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
dependencies = [
"phf_shared",
"rand",
]
[[package]]
name = "phf_shared"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5"
dependencies = [
"siphasher",
]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
[[package]]
name = "siphasher"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"

10
Cargo.toml Normal file
View File

@@ -0,0 +1,10 @@
[package]
name = "ircp2000"
version = "0.1.0"
edition = "2024"
[dependencies]
phf = "0.11.3"
[build-dependencies]
phf_codegen = "0.11.3"

55
build.rs Normal file
View File

@@ -0,0 +1,55 @@
use std::env;
use std::io::{BufWriter, Write};
use std::path::Path;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let path = Path::new(&env::var("OUT_DIR").unwrap()).join("capcodes.rs");
let mut file = BufWriter::new(std::fs::File::create(&path).unwrap());
let mut map = phf_codegen::Map::new();
let capcodelijst = std::fs::read_to_string("./capcodelijst.csv")?;
let mut codes = vec![];
for line in capcodelijst.lines() {
let capcode = line.split(";").next().unwrap_or_default().replace('"', "");
if !codes.contains(&capcode) {
codes.push(capcode.clone());
map.entry(capcode, &parse(line)?);
}
}
write!(
&mut file,
"static CAPCODES: phf::Map<&'static str, CapCode> = {}",
map.build()
)
.unwrap();
writeln!(&mut file, ";").unwrap();
println!("cargo::rerun-if-changed=capcodelijst.csv");
Ok(())
}
fn parse(s: &str) -> Result<String, Box<dyn std::error::Error>> {
let mut parts = s.split(';');
let capcode = parts.next().unwrap_or_default().replace('"', "");
let service = parts.next().unwrap_or_default().replace('"', "");
let region = parts.next().unwrap_or_default().replace('"', "");
let location = parts.next().unwrap_or_default().replace('"', "");
let description = parts.next().unwrap_or_default().replace('"', "");
// "0100005";"Brandweer";"Amsterdam-Amstelland";"Aalsmeer";"Officier van Dienst Aalsmeer/UitHoorn";""
Ok(format!(
r#"CapCode {{
capcode: "{capcode}",
service: "{service}",
region: "{region}",
location: "{location}",
description: "{description}",
}}"#
))
}

9629
capcodelijst.csv Normal file

File diff suppressed because it is too large Load Diff

102
src/main.rs Normal file
View File

@@ -0,0 +1,102 @@
use std::{io, str::FromStr};
type Error = Box<dyn std::error::Error + Send + Sync>;
type Result<T> = std::result::Result<T, Error>;
#[derive(Debug)]
pub struct CapCode {
capcode: &'static str,
region: &'static str,
location: &'static str,
service: &'static str,
description: &'static str,
}
include!(concat!(env!("OUT_DIR"), "/capcodes.rs"));
#[derive(Debug)]
struct Message {
raw: String,
protocol: String,
timestamp: String,
flags: String,
frameid: String,
capcodes: Vec<&'static CapCode>,
format: String,
message: String,
}
impl FromStr for Message {
type Err = Error;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
let mut parts = s.split('|'); //.collect::<Vec<&str>>();
if parts.clone().count() != 7 {
return Err("Invalid message".into());
}
let Some(protocol) = parts.next() else {
return Err("Missing Protocol".into());
};
let Some(timestamp) = parts.next() else {
return Err("Missing Timestamp".into());
};
let Some(flags) = parts.next() else {
return Err("Missing Flags".into());
};
let Some(frameid) = parts.next() else {
return Err("Missing FrameID".into());
};
let Some(capcodes) = parts.next() else {
return Err("Missing Cap Codes".into());
};
let Some(format) = parts.next() else {
return Err("Missing Format".into());
};
let Some(message) = parts.next() else {
return Err("Missing Message".into());
};
let mut cc = vec![];
let parts = capcodes.split(' ');
for c in parts {
let c = &c[2..];
let Some(cap) = CAPCODES.get(c) else {
continue;
};
cc.push(cap);
}
Ok(Self {
raw: s.to_string(),
protocol: protocol.to_string(),
timestamp: timestamp.to_string(),
flags: flags.to_string(),
frameid: frameid.to_string(),
capcodes: cc,
format: format.to_string(),
message: message.trim().to_string(),
})
}
}
fn main() -> Result<()> {
let mut buffer = String::new();
let stdin = io::stdin(); // We get `Stdin` here.
while stdin.read_line(&mut buffer)? > 0 {
if let Err(e) = process(&buffer) {
eprintln!("Error: {:?}", e);
}
buffer.clear();
}
Ok(())
}
fn process(s: &str) -> Result<Message> {
let message = Message::from_str(s)?;
dbg!(&message);
Ok(message)
}