From 00b567928501053bf7a64d2e515dd37567429c57 Mon Sep 17 00:00:00 2001 From: Ahmed El-Helw Date: Wed, 13 Nov 2024 23:03:24 +0400 Subject: [PATCH] Support incidents for OSRM responses --- Package.swift | 2 +- android/build.gradle | 2 +- .../ferrostar/core/FerrostarCoreTest.kt | 3 +- .../Mock/MockNavigationState.swift | 3 +- .../FerrostarSwiftUI/TestFixtureFactory.swift | 3 +- apple/Sources/UniFFI/ferrostar.swift | 796 +++++++++++++++++- common/Cargo.lock | 2 +- common/ferrostar/Cargo.toml | 2 +- common/ferrostar/src/models.rs | 103 +++ .../src/navigation_controller/test_helpers.rs | 1 + .../src/routing_adapters/osrm/mod.rs | 12 +- .../src/routing_adapters/osrm/models.rs | 121 ++- ...ers__osrm__tests__parse_valhalla_osrm.snap | 23 + ...ts__parse_valhalla_osrm_with_via_ways.snap | 2 + .../src/routing_adapters/osrm/utilities.rs | 36 +- web/package.json | 2 +- 16 files changed, 1099 insertions(+), 14 deletions(-) diff --git a/Package.swift b/Package.swift index f8b5c7d5..609c8553 100644 --- a/Package.swift +++ b/Package.swift @@ -16,7 +16,7 @@ if useLocalFramework { path: "./common/target/ios/libferrostar-rs.xcframework" ) } else { - let releaseTag = "0.21.0" + let releaseTag = "0.22.0" let releaseChecksum = "1086da6011e474aaaae97555e33204afa6626df2f3c9042b2c1a91949d400066" binaryTarget = .binaryTarget( name: "FerrostarCoreRS", diff --git a/android/build.gradle b/android/build.gradle index d6532152..6cf448df 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -17,5 +17,5 @@ ext { allprojects { group = "com.stadiamaps.ferrostar" - version = "0.21.0" + version = "0.22.0" } diff --git a/android/core/src/androidTest/java/com/stadiamaps/ferrostar/core/FerrostarCoreTest.kt b/android/core/src/androidTest/java/com/stadiamaps/ferrostar/core/FerrostarCoreTest.kt index 4130105c..8289d525 100644 --- a/android/core/src/androidTest/java/com/stadiamaps/ferrostar/core/FerrostarCoreTest.kt +++ b/android/core/src/androidTest/java/com/stadiamaps/ferrostar/core/FerrostarCoreTest.kt @@ -122,7 +122,8 @@ class FerrostarCoreTest { triggerDistanceBeforeManeuver = 42.0)), spokenInstructions = listOf(), duration = 0.0, - annotations = null))) + annotations = null, + incidents = listOf()))) @Test fun test401UnauthorizedRouteResponse() = runTest { diff --git a/apple/Sources/FerrostarCore/Mock/MockNavigationState.swift b/apple/Sources/FerrostarCore/Mock/MockNavigationState.swift index 34802391..2c625d1f 100644 --- a/apple/Sources/FerrostarCore/Mock/MockNavigationState.swift +++ b/apple/Sources/FerrostarCore/Mock/MockNavigationState.swift @@ -68,7 +68,8 @@ public extension NavigationState { ), ], spokenInstructions: [], - annotations: nil + annotations: nil, + incidents: [] ), ], remainingWaypoints: [], diff --git a/apple/Sources/FerrostarSwiftUI/TestFixtureFactory.swift b/apple/Sources/FerrostarSwiftUI/TestFixtureFactory.swift index f41797dc..63b9229e 100644 --- a/apple/Sources/FerrostarSwiftUI/TestFixtureFactory.swift +++ b/apple/Sources/FerrostarSwiftUI/TestFixtureFactory.swift @@ -74,7 +74,8 @@ struct RouteStepFactory: TestFixtureFactory { instruction: "Walk west on \(roadNameBuilder(n))", visualInstructions: [visualInstructionBuilder(n)], spokenInstructions: [], - annotations: nil + annotations: nil, + incidents: [] ) } } diff --git a/apple/Sources/UniFFI/ferrostar.swift b/apple/Sources/UniFFI/ferrostar.swift index cd157817..5424234d 100644 --- a/apple/Sources/UniFFI/ferrostar.swift +++ b/apple/Sources/UniFFI/ferrostar.swift @@ -396,6 +396,22 @@ fileprivate class UniffiHandleMap { // Public interface members begin here. +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterUInt8: FfiConverterPrimitive { + typealias FfiType = UInt8 + typealias SwiftType = UInt8 + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> UInt8 { + return try lift(readInt(&buf)) + } + + public static func write(_ value: UInt8, into buf: inout [UInt8]) { + writeInt(&buf, lower(value)) + } +} + #if swift(>=5.8) @_documentation(visibility: private) #endif @@ -1676,6 +1692,67 @@ public func FfiConverterTypeBoundingBox_lower(_ value: BoundingBox) -> RustBuffe } +/** + * Details about congestion for an incident. + */ +public struct Congestion { + public var value: UInt8 + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(value: UInt8) { + self.value = value + } +} + + + +extension Congestion: Equatable, Hashable { + public static func ==(lhs: Congestion, rhs: Congestion) -> Bool { + if lhs.value != rhs.value { + return false + } + return true + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(value) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeCongestion: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Congestion { + return + try Congestion( + value: FfiConverterUInt8.read(from: &buf) + ) + } + + public static func write(_ value: Congestion, into buf: inout [UInt8]) { + FfiConverterUInt8.write(value.value, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeCongestion_lift(_ buf: RustBuffer) throws -> Congestion { + return try FfiConverterTypeCongestion.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeCongestion_lower(_ value: Congestion) -> RustBuffer { + return FfiConverterTypeCongestion.lower(value) +} + + /** * The direction in which the user/device is observed to be traveling. */ @@ -1935,6 +2012,227 @@ public func FfiConverterTypeHeading_lower(_ value: Heading) -> RustBuffer { } +/** + * Details about an incident + */ +public struct Incident { + public var id: String + public var incidentType: IncidentType + public var description: String? + public var longDescription: String? + public var creationTime: String? + public var startTime: String? + public var endTime: String? + public var impact: Impact? + public var lanesBlocked: [BlockedLane] + public var numLanesBlocked: UInt8? + public var congestion: Congestion? + public var closed: Bool? + public var geometryIndexStart: UInt64 + public var geometryIndexEnd: UInt64 + public var subType: String? + public var subTypeDescription: String? + public var iso31661Alpha2: String? + public var iso31661Alpha3: String? + public var affectedRoadNames: [String] + public var southWest: GeographicCoordinate + public var northEast: GeographicCoordinate + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(id: String, incidentType: IncidentType, description: String?, longDescription: String?, creationTime: String?, startTime: String?, endTime: String?, impact: Impact?, lanesBlocked: [BlockedLane], numLanesBlocked: UInt8?, congestion: Congestion?, closed: Bool?, geometryIndexStart: UInt64, geometryIndexEnd: UInt64, subType: String?, subTypeDescription: String?, iso31661Alpha2: String?, iso31661Alpha3: String?, affectedRoadNames: [String], southWest: GeographicCoordinate, northEast: GeographicCoordinate) { + self.id = id + self.incidentType = incidentType + self.description = description + self.longDescription = longDescription + self.creationTime = creationTime + self.startTime = startTime + self.endTime = endTime + self.impact = impact + self.lanesBlocked = lanesBlocked + self.numLanesBlocked = numLanesBlocked + self.congestion = congestion + self.closed = closed + self.geometryIndexStart = geometryIndexStart + self.geometryIndexEnd = geometryIndexEnd + self.subType = subType + self.subTypeDescription = subTypeDescription + self.iso31661Alpha2 = iso31661Alpha2 + self.iso31661Alpha3 = iso31661Alpha3 + self.affectedRoadNames = affectedRoadNames + self.southWest = southWest + self.northEast = northEast + } +} + + + +extension Incident: Equatable, Hashable { + public static func ==(lhs: Incident, rhs: Incident) -> Bool { + if lhs.id != rhs.id { + return false + } + if lhs.incidentType != rhs.incidentType { + return false + } + if lhs.description != rhs.description { + return false + } + if lhs.longDescription != rhs.longDescription { + return false + } + if lhs.creationTime != rhs.creationTime { + return false + } + if lhs.startTime != rhs.startTime { + return false + } + if lhs.endTime != rhs.endTime { + return false + } + if lhs.impact != rhs.impact { + return false + } + if lhs.lanesBlocked != rhs.lanesBlocked { + return false + } + if lhs.numLanesBlocked != rhs.numLanesBlocked { + return false + } + if lhs.congestion != rhs.congestion { + return false + } + if lhs.closed != rhs.closed { + return false + } + if lhs.geometryIndexStart != rhs.geometryIndexStart { + return false + } + if lhs.geometryIndexEnd != rhs.geometryIndexEnd { + return false + } + if lhs.subType != rhs.subType { + return false + } + if lhs.subTypeDescription != rhs.subTypeDescription { + return false + } + if lhs.iso31661Alpha2 != rhs.iso31661Alpha2 { + return false + } + if lhs.iso31661Alpha3 != rhs.iso31661Alpha3 { + return false + } + if lhs.affectedRoadNames != rhs.affectedRoadNames { + return false + } + if lhs.southWest != rhs.southWest { + return false + } + if lhs.northEast != rhs.northEast { + return false + } + return true + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(id) + hasher.combine(incidentType) + hasher.combine(description) + hasher.combine(longDescription) + hasher.combine(creationTime) + hasher.combine(startTime) + hasher.combine(endTime) + hasher.combine(impact) + hasher.combine(lanesBlocked) + hasher.combine(numLanesBlocked) + hasher.combine(congestion) + hasher.combine(closed) + hasher.combine(geometryIndexStart) + hasher.combine(geometryIndexEnd) + hasher.combine(subType) + hasher.combine(subTypeDescription) + hasher.combine(iso31661Alpha2) + hasher.combine(iso31661Alpha3) + hasher.combine(affectedRoadNames) + hasher.combine(southWest) + hasher.combine(northEast) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeIncident: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Incident { + return + try Incident( + id: FfiConverterString.read(from: &buf), + incidentType: FfiConverterTypeIncidentType.read(from: &buf), + description: FfiConverterOptionString.read(from: &buf), + longDescription: FfiConverterOptionString.read(from: &buf), + creationTime: FfiConverterOptionString.read(from: &buf), + startTime: FfiConverterOptionString.read(from: &buf), + endTime: FfiConverterOptionString.read(from: &buf), + impact: FfiConverterOptionTypeImpact.read(from: &buf), + lanesBlocked: FfiConverterSequenceTypeBlockedLane.read(from: &buf), + numLanesBlocked: FfiConverterOptionUInt8.read(from: &buf), + congestion: FfiConverterOptionTypeCongestion.read(from: &buf), + closed: FfiConverterOptionBool.read(from: &buf), + geometryIndexStart: FfiConverterUInt64.read(from: &buf), + geometryIndexEnd: FfiConverterUInt64.read(from: &buf), + subType: FfiConverterOptionString.read(from: &buf), + subTypeDescription: FfiConverterOptionString.read(from: &buf), + iso31661Alpha2: FfiConverterOptionString.read(from: &buf), + iso31661Alpha3: FfiConverterOptionString.read(from: &buf), + affectedRoadNames: FfiConverterSequenceString.read(from: &buf), + southWest: FfiConverterTypeGeographicCoordinate.read(from: &buf), + northEast: FfiConverterTypeGeographicCoordinate.read(from: &buf) + ) + } + + public static func write(_ value: Incident, into buf: inout [UInt8]) { + FfiConverterString.write(value.id, into: &buf) + FfiConverterTypeIncidentType.write(value.incidentType, into: &buf) + FfiConverterOptionString.write(value.description, into: &buf) + FfiConverterOptionString.write(value.longDescription, into: &buf) + FfiConverterOptionString.write(value.creationTime, into: &buf) + FfiConverterOptionString.write(value.startTime, into: &buf) + FfiConverterOptionString.write(value.endTime, into: &buf) + FfiConverterOptionTypeImpact.write(value.impact, into: &buf) + FfiConverterSequenceTypeBlockedLane.write(value.lanesBlocked, into: &buf) + FfiConverterOptionUInt8.write(value.numLanesBlocked, into: &buf) + FfiConverterOptionTypeCongestion.write(value.congestion, into: &buf) + FfiConverterOptionBool.write(value.closed, into: &buf) + FfiConverterUInt64.write(value.geometryIndexStart, into: &buf) + FfiConverterUInt64.write(value.geometryIndexEnd, into: &buf) + FfiConverterOptionString.write(value.subType, into: &buf) + FfiConverterOptionString.write(value.subTypeDescription, into: &buf) + FfiConverterOptionString.write(value.iso31661Alpha2, into: &buf) + FfiConverterOptionString.write(value.iso31661Alpha3, into: &buf) + FfiConverterSequenceString.write(value.affectedRoadNames, into: &buf) + FfiConverterTypeGeographicCoordinate.write(value.southWest, into: &buf) + FfiConverterTypeGeographicCoordinate.write(value.northEast, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeIncident_lift(_ buf: RustBuffer) throws -> Incident { + return try FfiConverterTypeIncident.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeIncident_lower(_ value: Incident) -> RustBuffer { + return FfiConverterTypeIncident.lower(value) +} + + /** * The content of a visual instruction. */ @@ -2318,6 +2616,10 @@ public struct RouteStep { * A list of json encoded strings representing annotations between each coordinate along the step. */ public var annotations: [String]? + /** + * A list of incidents that occur along the step. + */ + public var incidents: [Incident] // Default memberwise initializers are never public by default, so we // declare one manually. @@ -2349,7 +2651,10 @@ public struct RouteStep { */spokenInstructions: [SpokenInstruction], /** * A list of json encoded strings representing annotations between each coordinate along the step. - */annotations: [String]?) { + */annotations: [String]?, + /** + * A list of incidents that occur along the step. + */incidents: [Incident]) { self.geometry = geometry self.distance = distance self.duration = duration @@ -2358,6 +2663,7 @@ public struct RouteStep { self.visualInstructions = visualInstructions self.spokenInstructions = spokenInstructions self.annotations = annotations + self.incidents = incidents } } @@ -2389,6 +2695,9 @@ extension RouteStep: Equatable, Hashable { if lhs.annotations != rhs.annotations { return false } + if lhs.incidents != rhs.incidents { + return false + } return true } @@ -2401,6 +2710,7 @@ extension RouteStep: Equatable, Hashable { hasher.combine(visualInstructions) hasher.combine(spokenInstructions) hasher.combine(annotations) + hasher.combine(incidents) } } @@ -2419,7 +2729,8 @@ public struct FfiConverterTypeRouteStep: FfiConverterRustBuffer { instruction: FfiConverterString.read(from: &buf), visualInstructions: FfiConverterSequenceTypeVisualInstruction.read(from: &buf), spokenInstructions: FfiConverterSequenceTypeSpokenInstruction.read(from: &buf), - annotations: FfiConverterOptionSequenceString.read(from: &buf) + annotations: FfiConverterOptionSequenceString.read(from: &buf), + incidents: FfiConverterSequenceTypeIncident.read(from: &buf) ) } @@ -2432,6 +2743,7 @@ public struct FfiConverterTypeRouteStep: FfiConverterRustBuffer { FfiConverterSequenceTypeVisualInstruction.write(value.visualInstructions, into: &buf) FfiConverterSequenceTypeSpokenInstruction.write(value.spokenInstructions, into: &buf) FfiConverterOptionSequenceString.write(value.annotations, into: &buf) + FfiConverterSequenceTypeIncident.write(value.incidents, into: &buf) } } @@ -3183,6 +3495,115 @@ public func FfiConverterTypeWaypoint_lower(_ value: Waypoint) -> RustBuffer { return FfiConverterTypeWaypoint.lower(value) } +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. +/** + * The lane type blocked by the incident. + */ + +public enum BlockedLane { + + case left + case leftCenter + case leftTurnLane + case center + case right + case rightCenter + case rightTurnLane + case hov +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeBlockedLane: FfiConverterRustBuffer { + typealias SwiftType = BlockedLane + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> BlockedLane { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .left + + case 2: return .leftCenter + + case 3: return .leftTurnLane + + case 4: return .center + + case 5: return .right + + case 6: return .rightCenter + + case 7: return .rightTurnLane + + case 8: return .hov + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: BlockedLane, into buf: inout [UInt8]) { + switch value { + + + case .left: + writeInt(&buf, Int32(1)) + + + case .leftCenter: + writeInt(&buf, Int32(2)) + + + case .leftTurnLane: + writeInt(&buf, Int32(3)) + + + case .center: + writeInt(&buf, Int32(4)) + + + case .right: + writeInt(&buf, Int32(5)) + + + case .rightCenter: + writeInt(&buf, Int32(6)) + + + case .rightTurnLane: + writeInt(&buf, Int32(7)) + + + case .hov: + writeInt(&buf, Int32(8)) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeBlockedLane_lift(_ buf: RustBuffer) throws -> BlockedLane { + return try FfiConverterTypeBlockedLane.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeBlockedLane_lower(_ value: BlockedLane) -> RustBuffer { + return FfiConverterTypeBlockedLane.lower(value) +} + + + +extension BlockedLane: Equatable, Hashable {} + + + // Note that we don't yet support `indirect` for enums. // See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. /** @@ -3257,6 +3678,231 @@ extension CourseFiltering: Equatable, Hashable {} +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. +/** + * The impact of the incident that has occurred. + */ + +public enum Impact { + + case unknown + case critical + case major + case minor + case low +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeImpact: FfiConverterRustBuffer { + typealias SwiftType = Impact + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Impact { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .unknown + + case 2: return .critical + + case 3: return .major + + case 4: return .minor + + case 5: return .low + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: Impact, into buf: inout [UInt8]) { + switch value { + + + case .unknown: + writeInt(&buf, Int32(1)) + + + case .critical: + writeInt(&buf, Int32(2)) + + + case .major: + writeInt(&buf, Int32(3)) + + + case .minor: + writeInt(&buf, Int32(4)) + + + case .low: + writeInt(&buf, Int32(5)) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeImpact_lift(_ buf: RustBuffer) throws -> Impact { + return try FfiConverterTypeImpact.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeImpact_lower(_ value: Impact) -> RustBuffer { + return FfiConverterTypeImpact.lower(value) +} + + + +extension Impact: Equatable, Hashable {} + + + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. +/** + * The type of incident that has occurred. + */ + +public enum IncidentType { + + case accident + case congestion + case construction + case disabledVehicle + case laneRestriction + case massTransit + case miscellaneous + case otherNews + case plannedEvent + case roadClosure + case roadHazard + case weather +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeIncidentType: FfiConverterRustBuffer { + typealias SwiftType = IncidentType + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> IncidentType { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .accident + + case 2: return .congestion + + case 3: return .construction + + case 4: return .disabledVehicle + + case 5: return .laneRestriction + + case 6: return .massTransit + + case 7: return .miscellaneous + + case 8: return .otherNews + + case 9: return .plannedEvent + + case 10: return .roadClosure + + case 11: return .roadHazard + + case 12: return .weather + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: IncidentType, into buf: inout [UInt8]) { + switch value { + + + case .accident: + writeInt(&buf, Int32(1)) + + + case .congestion: + writeInt(&buf, Int32(2)) + + + case .construction: + writeInt(&buf, Int32(3)) + + + case .disabledVehicle: + writeInt(&buf, Int32(4)) + + + case .laneRestriction: + writeInt(&buf, Int32(5)) + + + case .massTransit: + writeInt(&buf, Int32(6)) + + + case .miscellaneous: + writeInt(&buf, Int32(7)) + + + case .otherNews: + writeInt(&buf, Int32(8)) + + + case .plannedEvent: + writeInt(&buf, Int32(9)) + + + case .roadClosure: + writeInt(&buf, Int32(10)) + + + case .roadHazard: + writeInt(&buf, Int32(11)) + + + case .weather: + writeInt(&buf, Int32(12)) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeIncidentType_lift(_ buf: RustBuffer) throws -> IncidentType { + return try FfiConverterTypeIncidentType.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeIncidentType_lower(_ value: IncidentType) -> RustBuffer { + return FfiConverterTypeIncidentType.lower(value) +} + + + +extension IncidentType: Equatable, Hashable {} + + + public enum InstantiationError { @@ -4556,6 +5202,30 @@ extension WaypointKind: Equatable, Hashable {} +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionUInt8: FfiConverterRustBuffer { + typealias SwiftType = UInt8? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterUInt8.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterUInt8.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + #if swift(>=5.8) @_documentation(visibility: private) #endif @@ -4628,6 +5298,30 @@ fileprivate struct FfiConverterOptionDouble: FfiConverterRustBuffer { } } +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionBool: FfiConverterRustBuffer { + typealias SwiftType = Bool? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterBool.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterBool.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + #if swift(>=5.8) @_documentation(visibility: private) #endif @@ -4652,6 +5346,30 @@ fileprivate struct FfiConverterOptionString: FfiConverterRustBuffer { } } +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionTypeCongestion: FfiConverterRustBuffer { + typealias SwiftType = Congestion? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterTypeCongestion.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterTypeCongestion.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + #if swift(>=5.8) @_documentation(visibility: private) #endif @@ -4772,6 +5490,30 @@ fileprivate struct FfiConverterOptionTypeVisualInstructionContent: FfiConverterR } } +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionTypeImpact: FfiConverterRustBuffer { + typealias SwiftType = Impact? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterTypeImpact.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterTypeImpact.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + #if swift(>=5.8) @_documentation(visibility: private) #endif @@ -4918,6 +5660,31 @@ fileprivate struct FfiConverterSequenceTypeGeographicCoordinate: FfiConverterRus } } +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeIncident: FfiConverterRustBuffer { + typealias SwiftType = [Incident] + + public static func write(_ value: [Incident], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeIncident.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [Incident] { + let len: Int32 = try readInt(&buf) + var seq = [Incident]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeIncident.read(from: &buf)) + } + return seq + } +} + #if swift(>=5.8) @_documentation(visibility: private) #endif @@ -5068,6 +5835,31 @@ fileprivate struct FfiConverterSequenceTypeWaypoint: FfiConverterRustBuffer { } } +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeBlockedLane: FfiConverterRustBuffer { + typealias SwiftType = [BlockedLane] + + public static func write(_ value: [BlockedLane], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeBlockedLane.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [BlockedLane] { + let len: Int32 = try readInt(&buf) + var seq = [BlockedLane]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeBlockedLane.read(from: &buf)) + } + return seq + } +} + #if swift(>=5.8) @_documentation(visibility: private) #endif diff --git a/common/Cargo.lock b/common/Cargo.lock index 23bdbede..16b001c1 100644 --- a/common/Cargo.lock +++ b/common/Cargo.lock @@ -400,7 +400,7 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "ferrostar" -version = "0.21.0" +version = "0.22.0" dependencies = [ "assert-json-diff", "geo", diff --git a/common/ferrostar/Cargo.toml b/common/ferrostar/Cargo.toml index 750571c0..d57f3431 100644 --- a/common/ferrostar/Cargo.toml +++ b/common/ferrostar/Cargo.toml @@ -2,7 +2,7 @@ lints.workspace = true [package] name = "ferrostar" -version = "0.21.0" +version = "0.22.0" readme = "README.md" description = "The core of modern turn-by-turn navigation." keywords = ["navigation", "routing", "valhalla", "osrm"] diff --git a/common/ferrostar/src/models.rs b/common/ferrostar/src/models.rs index 176c2890..02b6b46f 100644 --- a/common/ferrostar/src/models.rs +++ b/common/ferrostar/src/models.rs @@ -322,6 +322,8 @@ pub struct RouteStep { pub spoken_instructions: Vec, /// A list of json encoded strings representing annotations between each coordinate along the step. pub annotations: Option>, + /// A list of incidents that occur along the step. + pub incidents: Vec, } impl RouteStep { @@ -462,6 +464,107 @@ pub enum ManeuverModifier { SharpLeft, } +/// The type of incident that has occurred. +#[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(feature = "wasm-bindgen", derive(Tsify))] +#[cfg_attr(feature = "wasm-bindgen", tsify(into_wasm_abi, from_wasm_abi))] +#[serde(rename_all = "snake_case")] +pub enum IncidentType { + Accident, + Congestion, + Construction, + DisabledVehicle, + LaneRestriction, + MassTransit, + Miscellaneous, + OtherNews, + PlannedEvent, + RoadClosure, + RoadHazard, + Weather, +} + +/// The impact of the incident that has occurred. +#[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(feature = "wasm-bindgen", derive(Tsify))] +#[cfg_attr(feature = "wasm-bindgen", tsify(into_wasm_abi, from_wasm_abi))] +#[serde(rename_all = "lowercase")] +pub enum Impact { + Unknown, + Critical, + Major, + Minor, + Low, +} + +/// The lane type blocked by the incident. +#[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(feature = "wasm-bindgen", derive(Tsify))] +#[cfg_attr(feature = "wasm-bindgen", tsify(into_wasm_abi, from_wasm_abi))] +#[serde(rename_all = "lowercase")] +pub enum BlockedLane { + Left, + #[serde(rename = "left center")] + LeftCenter, + #[serde(rename = "left turn lane")] + LeftTurnLane, + Center, + Right, + #[serde(rename = "right center")] + RightCenter, + #[serde(rename = "right turn lane")] + RightTurnLane, + #[serde(rename = "hov")] + HOV, +} + +/// Details about congestion for an incident. +#[derive(Deserialize, Serialize, Debug, Clone, PartialEq)] +#[cfg_attr(feature = "uniffi", derive(uniffi::Record))] +#[cfg_attr(feature = "wasm-bindgen", serde(rename_all = "camelCase"))] +#[cfg_attr(feature = "wasm-bindgen", derive(Tsify))] +#[cfg_attr(feature = "wasm-bindgen", tsify(into_wasm_abi, from_wasm_abi))] +pub struct Congestion { + pub value: u8, +} + +/// Details about an incident +#[derive(Debug, Clone, PartialEq)] +#[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(feature = "wasm-bindgen", derive(Tsify))] +#[cfg_attr(feature = "wasm-bindgen", tsify(into_wasm_abi, from_wasm_abi))] +pub struct Incident { + pub id: String, + pub incident_type: IncidentType, + pub description: Option, + pub long_description: Option, + pub creation_time: Option, + pub start_time: Option, + pub end_time: Option, + pub impact: Option, + pub lanes_blocked: Vec, + pub num_lanes_blocked: Option, + pub congestion: Option, + pub closed: Option, + pub geometry_index_start: u64, + pub geometry_index_end: u64, + pub sub_type: Option, + pub sub_type_description: Option, + pub iso_3166_1_alpha2: Option, + pub iso_3166_1_alpha3: Option, + pub affected_road_names: Vec, + pub south_west: GeographicCoordinate, + pub north_east: GeographicCoordinate, +} + /// The content of a visual instruction. #[derive(Debug, Clone, Eq, PartialEq)] #[cfg_attr(feature = "uniffi", derive(uniffi::Record))] diff --git a/common/ferrostar/src/navigation_controller/test_helpers.rs b/common/ferrostar/src/navigation_controller/test_helpers.rs index ca39f075..6a94673c 100644 --- a/common/ferrostar/src/navigation_controller/test_helpers.rs +++ b/common/ferrostar/src/navigation_controller/test_helpers.rs @@ -31,6 +31,7 @@ pub fn gen_dummy_route_step( visual_instructions: vec![], spoken_instructions: vec![], annotations: None, + incidents: vec![], } } diff --git a/common/ferrostar/src/routing_adapters/osrm/mod.rs b/common/ferrostar/src/routing_adapters/osrm/mod.rs index 6a49acf4..f9a3242e 100644 --- a/common/ferrostar/src/routing_adapters/osrm/mod.rs +++ b/common/ferrostar/src/routing_adapters/osrm/mod.rs @@ -5,7 +5,7 @@ pub mod utilities; use super::RouteResponseParser; use crate::models::{ - AnyAnnotationValue, GeographicCoordinate, LaneInfo, RouteStep, SpokenInstruction, + AnyAnnotationValue, GeographicCoordinate, Incident, LaneInfo, RouteStep, SpokenInstruction, VisualInstruction, VisualInstructionContent, Waypoint, WaypointKind, }; use crate::routing_adapters::utilities::get_coordinates_from_geometry; @@ -101,6 +101,13 @@ impl Route { .as_ref() .map(|leg_annotation| utilities::zip_annotations(leg_annotation.clone())); + // Convert all incidents into a vector of Incident objects. + let incident_items = leg + .incidents + .iter() + .map(|incident| utilities::convert_incident(incident)) + .collect::>(); + // Index for the annotations slice let mut start_index: usize = 0; @@ -126,6 +133,7 @@ impl Route { step, step_geometry, annotation_slice, + incident_items.clone(), ); }); }) @@ -151,6 +159,7 @@ impl RouteStep { value: &OsrmRouteStep, geometry: Vec, annotations: Option>, + incidents: Vec, ) -> Result { let visual_instructions = value .banner_instructions @@ -232,6 +241,7 @@ impl RouteStep { visual_instructions, spoken_instructions, annotations: annotations_as_strings, + incidents, }) } } diff --git a/common/ferrostar/src/routing_adapters/osrm/models.rs b/common/ferrostar/src/routing_adapters/osrm/models.rs index c8b97a0d..1119fdc7 100644 --- a/common/ferrostar/src/routing_adapters/osrm/models.rs +++ b/common/ferrostar/src/routing_adapters/osrm/models.rs @@ -4,7 +4,9 @@ //! by others which are now pseudo-standardized (ex: Mapbox). We omit some fields which are not //! needed for navigation. -use crate::models::{ManeuverModifier, ManeuverType}; +use crate::models::{ + BlockedLane, Congestion, Impact, IncidentType, ManeuverModifier, ManeuverType, +}; use alloc::{string::String, vec::Vec}; use serde::Deserialize; use serde_json::Value; @@ -67,6 +69,9 @@ pub struct RouteLeg { /// A Mapbox and Valhalla extension which indicates which waypoints are passed through rather than creating a new leg. #[serde(default)] pub via_waypoints: Vec, + /// Incidents along the route. + #[serde(default)] + pub incidents: Vec, } #[derive(Deserialize, Debug, Clone, PartialEq)] @@ -75,6 +80,36 @@ pub struct AnyAnnotation { pub values: HashMap>, } +#[derive(Deserialize, Debug)] +pub struct OsrmIncident { + pub id: String, + #[serde(rename = "type")] + pub incident_type: IncidentType, + pub description: Option, + pub long_description: Option, + pub creation_time: Option, + pub start_time: Option, + pub end_time: Option, + pub impact: Option, + #[serde(default)] + pub lanes_blocked: Vec, + pub num_lanes_blocked: Option, + pub congestion: Option, + pub closed: Option, + pub geometry_index_start: u64, + pub geometry_index_end: u64, + pub sub_type: Option, + pub sub_type_description: Option, + pub iso_3166_1_alpha2: Option, + pub iso_3166_1_alpha3: Option, + #[serde(default)] + pub affected_road_names: Vec, + pub south: f64, + pub west: f64, + pub north: f64, + pub east: f64, +} + #[derive(Deserialize, Debug)] pub struct RouteStep { /// The distance from the start of the current maneuver to the following step, in meters. @@ -500,4 +535,88 @@ mod tests { Some(vec!["right".to_string()]) ); } + + #[test] + fn deserialize_incidents() { + let data = r#" + { + "id": "13956787949218641", + "type": "construction", + "creation_time": "2024-11-13T16:39:17Z", + "start_time": "2023-04-03T22:00:00Z", + "end_time": "2024-11-26T04:59:00Z", + "iso_3166_1_alpha2": "US", + "iso_3166_1_alpha3": "USA", + "description": "I-84 W/B: intermittent lane closures from Exit 57 CT-15 to US-44 Connecticut Blvd", + "long_description": "Intermittent lane closures due to barrier repairs on I-84 Westbound from Exit 57 CT-15 to US-44 Connecticut Blvd.", + "impact": "major", + "sub_type": "CONSTRUCTION", + "alertc_codes": [ + 701, + 703 + ], + "traffic_codes": { + "incident_primary_code": 701 + }, + "lanes_blocked": [], + "length": 2403, + "south": 41.763362, + "west": -72.661148, + "north": 41.769363, + "east": -72.633712, + "congestion": { + "value": 101 + }, + "geometry_index_start": 2932, + "geometry_index_end": 3017, + "affected_road_names": [ + "Officer Brian A. Aselton Memorial Highway" + ], + "affected_road_names_unknown": [ + "I 84 West/US 6" + ], + "affected_road_names_en": [ + "Officer Brian A. Aselton Memorial Highway" + ] + } + "#; + + let incident: OsrmIncident = serde_json::from_str(data).expect("Failed to parse Incident"); + + // help me finish this test + assert_eq!(incident.id, "13956787949218641"); + assert_eq!(incident.incident_type, IncidentType::Construction); + assert_eq!( + incident.creation_time, + Some("2024-11-13T16:39:17Z".to_string()) + ); + assert_eq!( + incident.start_time, + Some("2023-04-03T22:00:00Z".to_string()) + ); + assert_eq!(incident.end_time, Some("2024-11-26T04:59:00Z".to_string())); + assert_eq!(incident.iso_3166_1_alpha2, Some("US".to_string())); + assert_eq!(incident.iso_3166_1_alpha3, Some("USA".to_string())); + assert_eq!( + incident.description, + Some( + "I-84 W/B: intermittent lane closures from Exit 57 CT-15 to US-44 Connecticut Blvd" + .to_string() + ) + ); + assert_eq!(incident.impact, Some(Impact::Major)); + assert_eq!(incident.sub_type, Some("CONSTRUCTION".to_string())); + assert_eq!(incident.lanes_blocked, vec![]); + assert_eq!(incident.south, 41.763362); + assert_eq!(incident.west, -72.661148); + assert_eq!(incident.north, 41.769363); + assert_eq!(incident.east, -72.633712); + assert_eq!(incident.congestion.unwrap().value, 101); + assert_eq!(incident.geometry_index_start, 2932); + assert_eq!(incident.geometry_index_end, 3017); + assert_eq!( + incident.affected_road_names, + vec!["Officer Brian A. Aselton Memorial Highway"] + ); + } } diff --git a/common/ferrostar/src/routing_adapters/osrm/snapshots/ferrostar__routing_adapters__osrm__tests__parse_valhalla_osrm.snap b/common/ferrostar/src/routing_adapters/osrm/snapshots/ferrostar__routing_adapters__osrm__tests__parse_valhalla_osrm.snap index 05119e3f..57e5b7a8 100644 --- a/common/ferrostar/src/routing_adapters/osrm/snapshots/ferrostar__routing_adapters__osrm__tests__parse_valhalla_osrm.snap +++ b/common/ferrostar/src/routing_adapters/osrm/snapshots/ferrostar__routing_adapters__osrm__tests__parse_valhalla_osrm.snap @@ -338,6 +338,7 @@ expression: routes ssml: "In 200 feet, Turn left onto the walkway." trigger_distance_before_maneuver: 60 annotations: redacted annotations json strings vec + incidents: [] - geometry: - lat: 59.442754 lng: 24.763449 @@ -362,6 +363,7 @@ expression: routes ssml: "In 14 feet, Turn right onto Laeva." trigger_distance_before_maneuver: 4.5 annotations: redacted annotations json strings vec + incidents: [] - geometry: - lat: 59.442671 lng: 24.763423 @@ -386,6 +388,7 @@ expression: routes ssml: "In 26 feet, Bear right." trigger_distance_before_maneuver: 8 annotations: redacted annotations json strings vec + incidents: [] - geometry: - lat: 59.442709 lng: 24.763155 @@ -412,6 +415,7 @@ expression: routes ssml: "In 24 feet, Bear left onto the walkway." trigger_distance_before_maneuver: 7.5 annotations: redacted annotations json strings vec + incidents: [] - geometry: - lat: 59.442819 lng: 24.763 @@ -440,6 +444,7 @@ expression: routes ssml: "In 62 feet, Continue." trigger_distance_before_maneuver: 19 annotations: redacted annotations json strings vec + incidents: [] - geometry: - lat: 59.442918 lng: 24.762356 @@ -464,6 +469,7 @@ expression: routes ssml: "In 11 feet, Turn right onto Admiralisild/Admiral Bridge." trigger_distance_before_maneuver: 3.5 annotations: redacted annotations json strings vec + incidents: [] - geometry: - lat: 59.442936 lng: 24.762237 @@ -494,6 +500,7 @@ expression: routes ssml: "In 200 feet, Continue on the walkway." trigger_distance_before_maneuver: 60 annotations: redacted annotations json strings vec + incidents: [] - geometry: - lat: 59.443526 lng: 24.761765 @@ -520,6 +527,7 @@ expression: routes ssml: "In 75 feet, Turn left onto the walkway." trigger_distance_before_maneuver: 23 annotations: redacted annotations json strings vec + incidents: [] - geometry: - lat: 59.4439 lng: 24.761432 @@ -544,6 +552,7 @@ expression: routes ssml: "In 200 feet, Turn right onto the walkway." trigger_distance_before_maneuver: 60 annotations: redacted annotations json strings vec + incidents: [] - geometry: - lat: 59.443487 lng: 24.759273 @@ -574,6 +583,7 @@ expression: routes ssml: "In 41 feet, Turn left onto the walkway." trigger_distance_before_maneuver: 12.5 annotations: redacted annotations json strings vec + incidents: [] - geometry: - lat: 59.443712 lng: 24.759127 @@ -602,6 +612,7 @@ expression: routes ssml: "In 26 feet, Turn right onto Logi." trigger_distance_before_maneuver: 8 annotations: redacted annotations json strings vec + incidents: [] - geometry: - lat: 59.443674 lng: 24.758853 @@ -644,6 +655,7 @@ expression: routes ssml: "In 200 feet, Turn left onto the walkway." trigger_distance_before_maneuver: 60 annotations: redacted annotations json strings vec + incidents: [] - geometry: - lat: 59.444448 lng: 24.758392 @@ -668,6 +680,7 @@ expression: routes ssml: "In 13 feet, Turn right onto the walkway." trigger_distance_before_maneuver: 4 annotations: redacted annotations json strings vec + incidents: [] - geometry: - lat: 59.444431 lng: 24.758246 @@ -698,6 +711,7 @@ expression: routes ssml: "In 200 feet, Bear left onto Kultuurikilomeeter." trigger_distance_before_maneuver: 60 annotations: redacted annotations json strings vec + incidents: [] - geometry: - lat: 59.445069 lng: 24.757636 @@ -828,6 +842,7 @@ expression: routes ssml: "In 200 feet, Turn right onto the walkway." trigger_distance_before_maneuver: 60 annotations: redacted annotations json strings vec + incidents: [] - geometry: - lat: 59.44946 lng: 24.739543 @@ -854,6 +869,7 @@ expression: routes ssml: "In 37 feet, Turn left onto the walkway." trigger_distance_before_maneuver: 11.5 annotations: redacted annotations json strings vec + incidents: [] - geometry: - lat: 59.449652 lng: 24.739675 @@ -880,6 +896,7 @@ expression: routes ssml: "In 26 feet, Turn left onto the crosswalk." trigger_distance_before_maneuver: 8 annotations: redacted annotations json strings vec + incidents: [] - geometry: - lat: 59.449733 lng: 24.739454 @@ -942,6 +959,7 @@ expression: routes ssml: "In 200 feet, Turn right onto the walkway." trigger_distance_before_maneuver: 60 annotations: redacted annotations json strings vec + incidents: [] - geometry: - lat: 59.450765 lng: 24.733721 @@ -966,6 +984,7 @@ expression: routes ssml: "In 3 feet, Turn left onto the walkway." trigger_distance_before_maneuver: 1 annotations: redacted annotations json strings vec + incidents: [] - geometry: - lat: 59.450787 lng: 24.733717 @@ -1016,6 +1035,7 @@ expression: routes ssml: "In 200 feet, Bear left onto Allveelaeva." trigger_distance_before_maneuver: 60 annotations: redacted annotations json strings vec + incidents: [] - geometry: - lat: 59.451907 lng: 24.730259 @@ -1040,6 +1060,7 @@ expression: routes ssml: "In 45 feet, Turn right onto Peetri." trigger_distance_before_maneuver: 14 annotations: redacted annotations json strings vec + incidents: [] - geometry: - lat: 59.452026 lng: 24.729829 @@ -1066,6 +1087,7 @@ expression: routes ssml: "In 41 feet, You have arrived at your destination." trigger_distance_before_maneuver: 12.5495 annotations: redacted annotations json strings vec + incidents: [] - geometry: - lat: 59.452226 lng: 24.730034 @@ -1087,3 +1109,4 @@ expression: routes trigger_distance_before_maneuver: 0 spoken_instructions: [] annotations: redacted annotations json strings vec + incidents: [] diff --git a/common/ferrostar/src/routing_adapters/osrm/snapshots/ferrostar__routing_adapters__osrm__tests__parse_valhalla_osrm_with_via_ways.snap b/common/ferrostar/src/routing_adapters/osrm/snapshots/ferrostar__routing_adapters__osrm__tests__parse_valhalla_osrm_with_via_ways.snap index 60430485..c0b66e45 100644 --- a/common/ferrostar/src/routing_adapters/osrm/snapshots/ferrostar__routing_adapters__osrm__tests__parse_valhalla_osrm_with_via_ways.snap +++ b/common/ferrostar/src/routing_adapters/osrm/snapshots/ferrostar__routing_adapters__osrm__tests__parse_valhalla_osrm_with_via_ways.snap @@ -452,6 +452,7 @@ expression: routes ssml: "In 200 feet, You have arrived at your destination." trigger_distance_before_maneuver: 60 annotations: redacted annotations json strings vec + incidents: [] - geometry: - lat: 28.790106 lng: -82.018021 @@ -473,3 +474,4 @@ expression: routes trigger_distance_before_maneuver: 0 spoken_instructions: [] annotations: redacted annotations json strings vec + incidents: [] diff --git a/common/ferrostar/src/routing_adapters/osrm/utilities.rs b/common/ferrostar/src/routing_adapters/osrm/utilities.rs index e7a5ced7..d7995277 100644 --- a/common/ferrostar/src/routing_adapters/osrm/utilities.rs +++ b/common/ferrostar/src/routing_adapters/osrm/utilities.rs @@ -1,5 +1,5 @@ -use super::models::AnyAnnotation; -use crate::models::AnyAnnotationValue; +use super::models::{AnyAnnotation, OsrmIncident}; +use crate::models::{AnyAnnotationValue, GeographicCoordinate, Incident}; use crate::routing_adapters::error::ParsingError; use serde_json::Value; use std::collections::HashMap; @@ -47,6 +47,38 @@ pub(crate) fn zip_annotations(annotation: AnyAnnotation) -> Vec>(); } +pub(crate) fn convert_incident(incident: &OsrmIncident) -> Incident { + Incident { + id: incident.id.clone(), + incident_type: incident.incident_type, + description: incident.description.clone(), + long_description: incident.long_description.clone(), + creation_time: incident.creation_time.clone(), + start_time: incident.start_time.clone(), + end_time: incident.end_time.clone(), + impact: incident.impact, + lanes_blocked: incident.lanes_blocked.clone(), + num_lanes_blocked: incident.num_lanes_blocked, + congestion: incident.congestion.clone(), + closed: incident.closed, + geometry_index_start: incident.geometry_index_start, + geometry_index_end: incident.geometry_index_end, + sub_type: incident.sub_type.clone(), + sub_type_description: incident.sub_type_description.clone(), + iso_3166_1_alpha2: incident.iso_3166_1_alpha2.clone(), + iso_3166_1_alpha3: incident.iso_3166_1_alpha3.clone(), + affected_road_names: incident.affected_road_names.clone(), + south_west: GeographicCoordinate { + lat: incident.south, + lng: incident.west, + }, + north_east: GeographicCoordinate { + lat: incident.north, + lng: incident.east, + }, + } +} + #[cfg(test)] mod test { diff --git a/web/package.json b/web/package.json index cb40352a..e869fc58 100644 --- a/web/package.json +++ b/web/package.json @@ -6,7 +6,7 @@ "CatMe0w (https://github.com/CatMe0w)", "Luke Seelenbinder " ], - "version": "0.21.0", + "version": "0.22.0", "license": "BSD-3-Clause", "type": "module", "main": "./dist/ferrostar-webcomponents.js",