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