initial commit
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/target
|
70
Cargo.lock
generated
Normal file
70
Cargo.lock
generated
Normal 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
10
Cargo.toml
Normal 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
55
build.rs
Normal 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
9629
capcodelijst.csv
Normal file
File diff suppressed because it is too large
Load Diff
102
src/main.rs
Normal file
102
src/main.rs
Normal 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)
|
||||
}
|
Reference in New Issue
Block a user