diff --git a/common/.cargo/config.toml b/common/.cargo/config.toml new file mode 100644 index 00000000..986d41c9 --- /dev/null +++ b/common/.cargo/config.toml @@ -0,0 +1,2 @@ +[env] +TS_RS_EXPORT_DIR = { value = "ferrostar/pkg", relative = true } \ No newline at end of file diff --git a/common/Cargo.lock b/common/Cargo.lock index de9fa973..50d0e731 100644 --- a/common/Cargo.lock +++ b/common/Cargo.lock @@ -341,6 +341,7 @@ dependencies = [ "serde-wasm-bindgen", "serde_json", "thiserror", + "ts-rs", "uniffi", "uuid", "wasm-bindgen", @@ -1067,6 +1068,15 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + [[package]] name = "textwrap" version = "0.16.1" @@ -1122,6 +1132,28 @@ dependencies = [ "winnow", ] +[[package]] +name = "ts-rs" +version = "9.0.1" +source = "git+https://github.com/Aleph-Alpha/ts-rs#78591a2831354243bb9eae5e254a8bcb85baffd9" +dependencies = [ + "lazy_static", + "thiserror", + "ts-rs-macros", + "uuid", +] + +[[package]] +name = "ts-rs-macros" +version = "9.0.1" +source = "git+https://github.com/Aleph-Alpha/ts-rs#78591a2831354243bb9eae5e254a8bcb85baffd9" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "termcolor", +] + [[package]] name = "unarray" version = "0.1.4" @@ -1430,6 +1462,15 @@ dependencies = [ "nom", ] +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys", +] + [[package]] name = "windows-sys" version = "0.52.0" diff --git a/common/ferrostar/Cargo.toml b/common/ferrostar/Cargo.toml index e4303de7..67dc10cd 100644 --- a/common/ferrostar/Cargo.toml +++ b/common/ferrostar/Cargo.toml @@ -43,6 +43,7 @@ proptest = { version = "1.4.0", default-features = false } insta = { version = "1.33.0", features = ["yaml"] } rstest = "0.21.0" wasm-bindgen-test = "0.3" +ts-rs = { git = "https://github.com/Aleph-Alpha/ts-rs", features = ["uuid-impl"] } [lib] crate-type = ["cdylib", "staticlib", "lib"] diff --git a/common/ferrostar/src/deviation_detection.rs b/common/ferrostar/src/deviation_detection.rs index d4a457a4..fcf45d8b 100644 --- a/common/ferrostar/src/deviation_detection.rs +++ b/common/ferrostar/src/deviation_detection.rs @@ -28,6 +28,7 @@ use { navigation_controller::test_helpers::{gen_dummy_route_step, gen_route_from_steps}, }, proptest::prelude::*, + ts_rs::TS, }; #[cfg(all(test, feature = "std", not(feature = "web-time")))] @@ -40,6 +41,8 @@ use web_time::SystemTime; #[derive(Clone)] #[cfg_attr(feature = "uniffi", derive(uniffi::Enum))] #[cfg_attr(feature = "wasm-bindgen", derive(Deserialize))] +#[cfg_attr(test, derive(TS))] +#[cfg_attr(test, ts(export, export_to = "types.d.ts"))] pub enum RouteDeviationTracking { /// No checks will be done, and we assume the user is always following the route. None, @@ -59,6 +62,7 @@ pub enum RouteDeviationTracking { /// An arbitrary user-defined implementation. /// You decide with your own [`RouteDeviationDetector`] implementation! #[cfg_attr(feature = "wasm-bindgen", serde(skip))] + #[cfg_attr(test, ts(skip))] Custom { detector: Arc, }, @@ -112,6 +116,8 @@ impl RouteDeviationTracking { #[derive(Debug, Copy, Clone, PartialEq)] #[cfg_attr(feature = "uniffi", derive(uniffi::Enum))] #[cfg_attr(feature = "wasm-bindgen", derive(Serialize, Deserialize))] +#[cfg_attr(test, derive(TS))] +#[cfg_attr(test, ts(export, export_to = "types.d.ts"))] pub enum RouteDeviation { /// The user is proceeding on course within the expected tolerances; everything is normal. NoDeviation, diff --git a/common/ferrostar/src/models.rs b/common/ferrostar/src/models.rs index 7d00d32d..c0b94a77 100644 --- a/common/ferrostar/src/models.rs +++ b/common/ferrostar/src/models.rs @@ -23,6 +23,12 @@ use web_time::SystemTime; #[cfg(any(test, feature = "wasm-bindgen"))] use serde::Serialize; +#[cfg(feature = "wasm-bindgen")] +use wasm_bindgen::prelude::*; + +#[cfg(test)] +use ts_rs::TS; + use uuid::Uuid; #[derive(Debug)] @@ -40,6 +46,8 @@ pub enum ModelError { #[derive(Clone, Copy, PartialEq, PartialOrd, Debug)] #[cfg_attr(feature = "uniffi", derive(uniffi::Record))] #[cfg_attr(any(feature = "wasm-bindgen", test), derive(Serialize, Deserialize))] +#[cfg_attr(test, derive(TS))] +#[cfg_attr(test, ts(export, export_to = "types.d.ts"))] pub struct GeographicCoordinate { /// The latitude (in degrees). pub lat: f64, @@ -94,6 +102,8 @@ impl From for Point { #[derive(Clone, Copy, PartialEq, PartialOrd, Debug)] #[cfg_attr(feature = "uniffi", derive(uniffi::Record))] #[cfg_attr(any(feature = "wasm-bindgen", test), derive(Serialize, Deserialize))] +#[cfg_attr(test, derive(TS))] +#[cfg_attr(test, ts(export, export_to = "types.d.ts"))] pub struct Waypoint { pub coordinate: GeographicCoordinate, pub kind: WaypointKind, @@ -103,6 +113,8 @@ pub struct Waypoint { #[derive(Clone, Copy, PartialEq, PartialOrd, Debug)] #[cfg_attr(feature = "uniffi", derive(uniffi::Enum))] #[cfg_attr(any(feature = "wasm-bindgen", test), derive(Serialize, Deserialize))] +#[cfg_attr(test, derive(TS))] +#[cfg_attr(test, ts(export, export_to = "types.d.ts"))] pub enum WaypointKind { /// Starts or ends a leg of the trip. /// @@ -116,6 +128,8 @@ pub enum WaypointKind { #[derive(Clone, Copy, PartialEq, PartialOrd, Debug)] #[cfg_attr(feature = "uniffi", derive(uniffi::Record))] #[cfg_attr(any(feature = "wasm-bindgen", test), derive(Serialize, Deserialize))] +#[cfg_attr(test, derive(TS))] +#[cfg_attr(test, ts(export, export_to = "types.d.ts"))] pub struct BoundingBox { /// The southwest corner of the bounding box. pub sw: GeographicCoordinate, @@ -148,6 +162,8 @@ pub struct Heading { #[derive(Clone, Copy, PartialEq, PartialOrd, Debug)] #[cfg_attr(feature = "uniffi", derive(uniffi::Record))] #[cfg_attr(any(feature = "wasm-bindgen", test), derive(Serialize, Deserialize))] +#[cfg_attr(test, derive(TS))] +#[cfg_attr(test, ts(export, export_to = "types.d.ts"))] pub struct CourseOverGround { /// The direction in which the user's device is traveling, measured in clockwise degrees from /// true north (N = 0, E = 90, S = 180, W = 270). @@ -166,6 +182,8 @@ impl CourseOverGround { #[derive(Clone, Copy, PartialEq, PartialOrd, Debug)] #[cfg_attr(feature = "uniffi", derive(uniffi::Record))] #[cfg_attr(any(feature = "wasm-bindgen", test), derive(Serialize, Deserialize))] +#[cfg_attr(test, derive(TS))] +#[cfg_attr(test, ts(export, export_to = "types.d.ts"))] pub struct Speed { /// The user's speed in meters per second. pub value: f64, @@ -214,6 +232,8 @@ mod system_time_format { #[cfg_attr(feature = "uniffi", derive(uniffi::Record))] #[cfg_attr(any(feature = "wasm-bindgen", test), derive(Serialize, Deserialize))] #[cfg_attr(feature = "wasm-bindgen", serde(rename_all = "camelCase"))] +#[cfg_attr(test, derive(TS))] +#[cfg_attr(test, ts(export, export_to = "types.d.ts"))] pub struct UserLocation { pub coordinates: GeographicCoordinate, /// The estimated accuracy of the coordinate (in meters) @@ -221,6 +241,7 @@ pub struct UserLocation { pub course_over_ground: Option, #[cfg_attr(test, serde(skip_serializing))] #[cfg_attr(feature = "wasm-bindgen", serde(with = "system_time_format"))] + #[cfg_attr(test, ts(as = "u64"))] pub timestamp: SystemTime, pub speed: Option, } @@ -238,6 +259,8 @@ impl From for Point { #[derive(Clone, Debug)] #[cfg_attr(feature = "uniffi", derive(uniffi::Record))] #[cfg_attr(any(feature = "wasm-bindgen", test), derive(Serialize, Deserialize))] +#[cfg_attr(test, derive(TS))] +#[cfg_attr(test, ts(export, export_to = "types.d.ts"))] pub struct Route { pub geometry: Vec, pub bbox: BoundingBox, @@ -269,6 +292,8 @@ fn get_route_polyline(route: &Route, precision: u32) -> Result, /// The distance, in meters, to travel along the route after the maneuver to reach the next step. @@ -338,6 +363,27 @@ impl RouteStep { } } +// #[cfg(feature = "wasm-bindgen")] +// mod uuid_format { +// use serde::{self, Deserialize, Deserializer, Serializer}; +// use uuid::Uuid; + +// pub fn serialize(uuid: &Uuid, serializer: S) -> Result +// where +// S: Serializer, +// { +// serializer.serialize_str(&uuid.to_string()) +// } + +// pub fn deserialize<'de, D>(deserializer: D) -> Result +// where +// D: Deserializer<'de>, +// { +// let s = String::deserialize(deserializer)?; +// Uuid::parse_str(&s).map_err(serde::de::Error::custom) +// } +// } + /// An instruction that can be synthesized using a TTS engine to announce an upcoming maneuver. /// /// Note that these do not have any locale information attached. @@ -345,6 +391,8 @@ impl RouteStep { #[cfg_attr(feature = "uniffi", derive(uniffi::Record))] #[cfg_attr(any(feature = "wasm-bindgen", test), derive(Serialize, Deserialize))] #[cfg_attr(feature = "wasm-bindgen", serde(rename_all = "camelCase"))] +#[cfg_attr(test, derive(TS))] +#[cfg_attr(test, ts(export, export_to = "types.d.ts"))] pub struct SpokenInstruction { /// Plain-text instruction which can be synthesized with a TTS engine. pub text: String, @@ -370,6 +418,8 @@ pub struct SpokenInstruction { #[derive(Deserialize, Debug, Copy, Clone, Eq, PartialEq)] #[cfg_attr(feature = "uniffi", derive(uniffi::Enum))] #[cfg_attr(any(test, feature = "wasm-bindgen"), derive(Serialize))] +#[cfg_attr(test, derive(TS))] +#[cfg_attr(test, ts(export, export_to = "types.d.ts"))] #[serde(rename_all = "lowercase")] pub enum ManeuverType { Turn, @@ -401,6 +451,8 @@ pub enum ManeuverType { #[derive(Deserialize, Debug, Copy, Clone, Eq, PartialEq)] #[cfg_attr(feature = "uniffi", derive(uniffi::Enum))] #[cfg_attr(any(test, feature = "wasm-bindgen"), derive(Serialize))] +#[cfg_attr(test, derive(TS))] +#[cfg_attr(test, ts(export, export_to = "types.d.ts"))] #[serde(rename_all = "lowercase")] pub enum ManeuverModifier { UTurn, @@ -422,6 +474,8 @@ pub enum ManeuverModifier { #[cfg_attr(feature = "uniffi", derive(uniffi::Record))] #[cfg_attr(any(feature = "wasm-bindgen", test), derive(Serialize, Deserialize))] #[cfg_attr(feature = "wasm-bindgen", serde(rename_all = "camelCase"))] +#[cfg_attr(test, derive(TS))] +#[cfg_attr(test, ts(export, export_to = "types.d.ts"))] pub struct VisualInstructionContent { /// The text to display. pub text: String, @@ -442,6 +496,8 @@ pub struct VisualInstructionContent { #[cfg_attr(feature = "uniffi", derive(uniffi::Record))] #[cfg_attr(any(feature = "wasm-bindgen", test), derive(Serialize, Deserialize))] #[cfg_attr(feature = "wasm-bindgen", serde(rename_all = "camelCase"))] +#[cfg_attr(test, derive(TS))] +#[cfg_attr(test, ts(export, export_to = "types.d.ts"))] pub struct VisualInstruction { /// The primary instruction content. /// @@ -453,6 +509,9 @@ pub struct VisualInstruction { pub trigger_distance_before_maneuver: f64, } +#[cfg_attr(feature = "wasm-bindgen", wasm_bindgen(typescript_custom_section))] +const TS_TYPES: &'static str = r#"/// "#; + #[cfg(test)] #[cfg(feature = "uniffi")] mod tests { diff --git a/common/ferrostar/src/navigation_controller/models.rs b/common/ferrostar/src/navigation_controller/models.rs index bd9e4a09..2e04260c 100644 --- a/common/ferrostar/src/navigation_controller/models.rs +++ b/common/ferrostar/src/navigation_controller/models.rs @@ -8,11 +8,16 @@ use geo::LineString; #[cfg(feature = "wasm-bindgen")] use serde::{Deserialize, Serialize}; +#[cfg(test)] +use ts_rs::TS; + /// High-level state describing progress through a route. #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "uniffi", derive(uniffi::Record))] #[cfg_attr(feature = "wasm-bindgen", derive(Serialize, Deserialize))] #[cfg_attr(feature = "wasm-bindgen", serde(rename_all = "camelCase"))] +#[cfg_attr(test, derive(TS))] +#[cfg_attr(test, ts(export, export_to = "types.d.ts"))] pub struct TripProgress { /// The distance to the next maneuver, in meters. pub distance_to_next_maneuver: f64, @@ -28,6 +33,8 @@ pub struct TripProgress { #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "uniffi", derive(uniffi::Enum))] #[cfg_attr(feature = "wasm-bindgen", derive(Serialize, Deserialize))] +#[cfg_attr(test, derive(TS))] +#[cfg_attr(test, ts(export, export_to = "types.d.ts"))] pub enum TripState { #[cfg_attr(feature = "wasm-bindgen", serde(rename_all = "camelCase"))] Navigating { @@ -76,6 +83,8 @@ pub enum StepAdvanceStatus { #[derive(Debug, Copy, Clone)] #[cfg_attr(feature = "uniffi", derive(uniffi::Enum))] #[cfg_attr(feature = "wasm-bindgen", derive(Deserialize))] +#[cfg_attr(test, derive(TS))] +#[cfg_attr(test, ts(export, export_to = "types.d.ts"))] pub enum StepAdvanceMode { /// Never advances to the next step automatically; /// requires calling [`NavigationController::advance_to_next_step`](super::NavigationController::advance_to_next_step). @@ -108,6 +117,8 @@ pub enum StepAdvanceMode { #[cfg_attr(feature = "uniffi", derive(uniffi::Record))] #[cfg_attr(feature = "wasm-bindgen", derive(Deserialize))] #[cfg_attr(feature = "wasm-bindgen", serde(rename_all = "camelCase"))] +#[cfg_attr(test, derive(TS))] +#[cfg_attr(test, ts(export, export_to = "types.d.ts"))] pub struct NavigationControllerConfig { pub step_advance: StepAdvanceMode, pub route_deviation_tracking: RouteDeviationTracking,