commit c3dfb55c0bcedc3e8141dbc1a460d4ec3d77b59f
parent 2f12947167c38ccf97fe106fa2c3c7a8ac767f65
Author: Yureka <yuka@yuka.dev>
Date: Mon, 2 May 2022 12:49:10 +0200
parent 2f12947167c38ccf97fe106fa2c3c7a8ac767f65
Author: Yureka <yuka@yuka.dev>
Date: Mon, 2 May 2022 12:49:10 +0200
fmt
1 file changed, 71 insertions(+), 49 deletions(-)
M
|
120
+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
diff --git a/trainsearch-refresh-token/src/lib.rs b/trainsearch-refresh-token/src/lib.rs @@ -1,8 +1,8 @@ -use std::convert::TryInto; use anyhow::anyhow; -use std::collections::HashMap; use chrono::NaiveDateTime; -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; +use std::convert::TryInto; #[cfg(feature = "wasm-bindings")] use wasm_bindgen::prelude::wasm_bindgen; @@ -16,19 +16,25 @@ pub enum HafasLegType { } fn read_byte(input: &mut &[u8]) -> anyhow::Result<u8> { - if input.len() < 1 { return Err(anyhow!("1 bytes")); } + if input.len() < 1 { + return Err(anyhow!("1 bytes")); + } let byte = input[0]; *input = &input[1..]; Ok(byte) } fn read_2_bytes(input: &mut &[u8]) -> anyhow::Result<[u8; 2]> { - if input.len() < 2 { return Err(anyhow!("2 bytes")); } + if input.len() < 2 { + return Err(anyhow!("2 bytes")); + } let res = input[..2].try_into()?; *input = &input[2..]; Ok(res) } fn read_4_bytes(input: &mut &[u8]) -> anyhow::Result<[u8; 4]> { - if input.len() < 4 { return Err(anyhow!("4 bytes")); } + if input.len() < 4 { + return Err(anyhow!("4 bytes")); + } let res = input[..4].try_into()?; *input = &input[4..]; Ok(res) @@ -45,7 +51,9 @@ fn encode_string_compressed(text: &str) -> anyhow::Result<Vec<u8>> { fn decode_string_compressed(input: &mut &[u8]) -> anyhow::Result<String> { let len = read_byte(input)? as usize; - if input.len() < len { return Err(anyhow!("dec string")) } + if input.len() < len { + return Err(anyhow!("dec string")); + } let compressed_string = &input[..len]; *input = &input[len..]; @@ -62,15 +70,15 @@ fn encode_string(text: &str) -> anyhow::Result<Vec<u8>> { fn decode_string(input: &mut &[u8]) -> anyhow::Result<String> { let len = read_byte(input)? as usize; - if input.len() < len { return Err(anyhow!("dec string")) } + if input.len() < len { + return Err(anyhow!("dec string")); + } let bytes = &input[..len]; *input = &input[len..]; Ok(String::from_utf8(bytes.to_vec())?) } - - fn encode_trainsearch_date(datetime: NaiveDateTime) -> anyhow::Result<u32> { Ok((datetime.timestamp() / 60).try_into()?) } @@ -91,20 +99,20 @@ fn encode_trainsearch_place(place: Place) -> anyhow::Result<Vec<u8>> { Place::Station { id } => { out.push(1); out.append(&mut id.to_le_bytes().to_vec()); - }, + } Place::Address { name, x, y } => { out.push(2); out.append(&mut encode_string_compressed(&name)?); out.append(&mut x.to_le_bytes().to_vec()); out.append(&mut y.to_le_bytes().to_vec()); - }, + } Place::Poi { id, name, x, y } => { out.push(4); out.append(&mut id.to_le_bytes().to_vec()); out.append(&mut encode_string_compressed(&name)?); out.append(&mut x.to_le_bytes().to_vec()); out.append(&mut y.to_le_bytes().to_vec()); - }, + } } Ok(out) } @@ -112,34 +120,32 @@ fn encode_trainsearch_place(place: Place) -> anyhow::Result<Vec<u8>> { fn decode_trainsearch_place(input: &mut &[u8]) -> anyhow::Result<Place> { let t = read_byte(input)?; Ok(match t { - 1 => { - Place::Station { - id: u32::from_le_bytes(read_4_bytes(input)?), - } + 1 => Place::Station { + id: u32::from_le_bytes(read_4_bytes(input)?), }, - 2 => { - Place::Address { - name: decode_string_compressed(input)?, - x: i32::from_le_bytes(read_4_bytes(input)?), - y: i32::from_le_bytes(read_4_bytes(input)?), - } + 2 => Place::Address { + name: decode_string_compressed(input)?, + x: i32::from_le_bytes(read_4_bytes(input)?), + y: i32::from_le_bytes(read_4_bytes(input)?), }, - 4 => { - Place::Poi { - id: u32::from_le_bytes(read_4_bytes(input)?), - name: decode_string_compressed(input)?, - x: i32::from_le_bytes(read_4_bytes(input)?), - y: i32::from_le_bytes(read_4_bytes(input)?), - } + 4 => Place::Poi { + id: u32::from_le_bytes(read_4_bytes(input)?), + name: decode_string_compressed(input)?, + x: i32::from_le_bytes(read_4_bytes(input)?), + y: i32::from_le_bytes(read_4_bytes(input)?), }, _ => return Err(anyhow!("unknown place type")), }) } fn decode_hafas_place(text: &str) -> anyhow::Result<Place> { - let content = text.split("@") - .collect::<Vec<_>>().into_iter() // make iterator reversible - .rev().skip(1).rev() // remove last item ("") + let content = text + .split("@") + .collect::<Vec<_>>() + .into_iter() // make iterator reversible + .rev() + .skip(1) + .rev() // remove last item ("") .map(|x| { let mut iter = x.split("="); let first = iter.next().ok_or(anyhow!("enc place 1"))?; @@ -151,20 +157,20 @@ fn decode_hafas_place(text: &str) -> anyhow::Result<Place> { Some(&"1") => { let id = content.get("L").ok_or(anyhow!("enc place 3"))?.parse()?; Place::Station { id } - }, + } Some(&"2") => { let name = content.get("O").ok_or(anyhow!("enc place 4"))?.to_string(); let x = content.get("X").ok_or(anyhow!("enc place 5"))?.parse()?; let y = content.get("Y").ok_or(anyhow!("enc place 6"))?.parse()?; Place::Address { name, x, y } - }, + } Some(&"4") => { let id = content.get("L").ok_or(anyhow!("enc place 7"))?.parse()?; let name = content.get("O").ok_or(anyhow!("enc place 8"))?.to_string(); let x = content.get("X").ok_or(anyhow!("enc place 9"))?.parse()?; let y = content.get("Y").ok_or(anyhow!("enc place 10"))?.parse()?; Place::Poi { name, x, y, id } - }, + } _ => return Err(anyhow!("enc place 11")), }) } @@ -175,22 +181,25 @@ fn encode_hafas_place(place: Place) -> anyhow::Result<String> { Place::Station { id } => { parts.push(("A", format!("{}", 1))); parts.push(("L", format!("{}", id))); - }, + } Place::Address { name, x, y } => { parts.push(("A", format!("{}", 2))); parts.push(("O", name)); parts.push(("X", format!("{}", x))); parts.push(("Y", format!("{}", y))); - }, + } Place::Poi { id, name, x, y } => { parts.push(("A", format!("{}", 4))); parts.push(("L", format!("{}", id))); parts.push(("O", name)); parts.push(("X", format!("{}", x))); parts.push(("Y", format!("{}", y))); - }, + } } - Ok(parts.into_iter().map(|(a, b)| format!("{}={}@", a, b)).collect::<String>()) + Ok(parts + .into_iter() + .map(|(a, b)| format!("{}={}@", a, b)) + .collect::<String>()) } pub struct HafasReconstructionContext { @@ -234,7 +243,10 @@ pub(crate) fn decode_hafas(token: &str) -> anyhow::Result<HafasReconstructionCon let mut parts = leg.split('$'); legs.push(HafasReconstructionContextLeg { - leg_type: match parts.next().ok_or_else(|| anyhow!("wrong number of parts"))? { + leg_type: match parts + .next() + .ok_or_else(|| anyhow!("wrong number of parts"))? + { "T" => HafasLegType::Journey, "G@F" => HafasLegType::Walk, "TF" => HafasLegType::Transfer, @@ -277,7 +289,9 @@ pub(crate) fn decode_hafas(token: &str) -> anyhow::Result<HafasReconstructionCon }, }); while let Some(part) = parts.next() { - if part != "" { return Err(anyhow!("unexpected field with content: {}", part)) } + if part != "" { + return Err(anyhow!("unexpected field with content: {}", part)); + } } } @@ -312,10 +326,17 @@ pub(crate) fn encode_hafas(data: HafasReconstructionContext) -> anyhow::Result<S pub(crate) fn encode_trainsearch(token: HafasReconstructionContext) -> anyhow::Result<String> { let mut out = vec![ - 0u8 // version + 0u8, // version ]; - out.append(&mut encode_trainsearch_place(token.legs.get(0).ok_or_else(|| anyhow!("token has no legs"))?.from.clone())?); + out.append(&mut encode_trainsearch_place( + token + .legs + .get(0) + .ok_or_else(|| anyhow!("token has no legs"))? + .from + .clone(), + )?); for leg in token.legs { out.push(match leg.leg_type { @@ -330,7 +351,8 @@ pub(crate) fn encode_trainsearch(token: HafasReconstructionContext) -> anyhow::R { let departure: u32 = encode_trainsearch_date(leg.departure)?; - let arrival_minus_departure: u16 = (encode_trainsearch_date(leg.arrival)? - departure).try_into()?; + let arrival_minus_departure: u16 = + (encode_trainsearch_date(leg.arrival)? - departure).try_into()?; out.append(&mut departure.to_le_bytes().to_vec()); out.append(&mut arrival_minus_departure.to_le_bytes().to_vec()); } @@ -364,10 +386,11 @@ pub(crate) fn decode_trainsearch(token: &str) -> anyhow::Result<HafasReconstruct let (departure, arrival) = { let departure = u32::from_le_bytes(read_4_bytes(&mut input)?); - let arrival_minus_departure = u16::from_le_bytes(read_2_bytes(&mut input)?) as u32; + let arrival_minus_departure = + u16::from_le_bytes(read_2_bytes(&mut input)?) as u32; ( decode_trainsearch_date(departure), - decode_trainsearch_date(departure + arrival_minus_departure) + decode_trainsearch_date(departure + arrival_minus_departure), ) }; @@ -386,7 +409,7 @@ pub(crate) fn decode_trainsearch(token: &str) -> anyhow::Result<HafasReconstruct last_place = to; } HafasReconstructionContext { legs } - }, + } _ => return Err(anyhow!("unknown trainsearch token version")), }) } @@ -408,4 +431,3 @@ pub fn wasm_trainsearch_to_hafas(token: &str) -> Result<String, String> { pub fn wasm_hafas_to_trainsearch(token: &str) -> Result<String, String> { hafas_to_trainsearch(token).map_err(|e| e.to_string()) } -