import gleam/dynamic/decode.{type Decoder} import gleam/json import gleam/option.{type Option} import models/agent.{type Agent} import models/chart.{type Chart} import models/chart_transaction.{type ChartTransaction} import models/contract.{type Contract} import models/cooldown.{type Cooldown} import models/extraction.{type Extraction} import models/market_transaction.{type MarketTransaction} import models/module_symbol.{type ModuleSymbol} import models/mount_symbol.{type MountSymbol} import models/refinement_produce.{type RefinementProduce} import models/refinement_yield.{type RefinementYield} import models/repair_transaction.{type RepairTransaction} import models/scanned_ship.{type ScannedShip} import models/scanned_system.{type ScannedSystem} import models/scanned_waypoint.{type ScannedWaypoint} import models/scrap_transaction.{type ScrapTransaction} import models/ship.{type Ship} import models/ship_cargo.{type ShipCargo} import models/ship_condition_event.{type ShipConditionEvent} import models/ship_fuel.{type ShipFuel} import models/ship_modification_transaction.{type ShipModificationTransaction} import models/ship_module.{type ShipModule} import models/ship_mount.{type ShipMount} import models/ship_nav.{type ShipNav} import models/ship_nav_flight_mode.{type ShipNavFlightMode} import models/ship_symbol.{type ShipSymbol} import models/ship_type.{type ShipType} import models/shipyard_transaction.{type ShipyardTransaction} import models/siphon.{type Siphon} import models/survey.{type Survey} import models/trade_symbol.{type TradeSymbol} import models/waypoint.{type Waypoint} import models/waypoint_modifier.{type WaypointModifier} import models/waypoint_symbol.{type WaypointSymbol} import utils/api.{type ApiResponse, type PagedData} import utils/auth.{type AgentToken, AgentAuth} pub fn list_ships( token: AgentToken, page: Option(Int), limit: Option(Int), ) -> ApiResponse(PagedData(List(Ship))) { let request = api.get_page(AgentAuth(token), "/my/ships", page, limit) use response <- api.try_send(request) case response.status { 200 -> api.parse_paged_data_response(response, decode.list(ship.decoder())) _ -> api.parse_error_response(response) } } pub type ShipPurchased { ShipPurchased(ship: Ship, agent: Agent, transaction: ShipyardTransaction) } pub fn purchase_ship( token: AgentToken, ship_type: ShipType, waypoint_symbol: WaypointSymbol, ) -> ApiResponse(ShipPurchased) { let request = api.post_json( AgentAuth(token), "/my/ships", json.object([ #("shipType", ship_type.encode(ship_type)), #("waypointSymbol", waypoint_symbol.encode(waypoint_symbol)), ]), ) use response <- api.try_send(request) case response.status { 201 -> api.parse_data_response(response, { use ship <- decode.field("ship", ship.decoder()) use agent <- decode.field("agent", agent.decoder()) use transaction <- decode.field( "transaction", shipyard_transaction.decoder(), ) decode.success(ShipPurchased(ship:, agent:, transaction:)) }) _ -> api.parse_error_response(response) } } pub fn get_ship(token: AgentToken, ship_symbol: ShipSymbol) -> ApiResponse(Ship) { let request = api.get( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol), ) use response <- api.try_send(request) case response.status { 200 -> api.parse_data_response(response, ship.decoder()) _ -> api.parse_error_response(response) } } pub type ChartCreated { ChartCreated( chart: Chart, waypoint: Waypoint, transaction: ChartTransaction, agent: Agent, ) } pub fn create_chart( token: AgentToken, ship_symbol: ShipSymbol, ) -> ApiResponse(ChartCreated) { let request = api.post( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/chart", ) use response <- api.try_send(request) case response.status { 201 -> api.parse_data_response(response, { use chart <- decode.field("chart", chart.decoder()) use waypoint <- decode.field("waypoint", waypoint.decoder()) use transaction <- decode.field( "transaction", chart_transaction.decoder(), ) use agent <- decode.field("agent", agent.decoder()) decode.success(ChartCreated(chart:, waypoint:, transaction:, agent:)) }) _ -> api.parse_error_response(response) } } pub fn negotiate_contract( token: AgentToken, ship_symbol: String, ) -> ApiResponse(Contract) { let request = api.post( AgentAuth(token), "/my/ships/" <> ship_symbol <> "/negotiate/contract", ) use response <- api.try_send(request) case response.status { 201 -> api.parse_data_response( response, decode.field("contract", contract.decoder(), decode.success), ) _ -> api.parse_error_response(response) } } pub fn get_ship_cooldown( token: AgentToken, ship_symbol: ShipSymbol, ) -> ApiResponse(Option(Cooldown)) { let request = api.get( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/cooldown", ) use response <- api.try_send(request) case response.status { 200 -> api.parse_data_response( response, decode.field("cooldown", cooldown.decoder(), fn(cooldown) { decode.success(option.Some(cooldown)) }), ) 204 -> Ok(option.None) _ -> api.parse_error_response(response) } } pub fn dock_ship( token: AgentToken, ship_symbol: ShipSymbol, ) -> ApiResponse(ShipNav) { let request = api.post( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/dock", ) use response <- api.try_send(request) case response.status { 200 -> api.parse_data_response( response, decode.field("nav", ship_nav.decoder(), decode.success), ) _ -> api.parse_error_response(response) } } pub type ResourcesExtracted { ResourcesExtracted( extraction: Extraction, cooldown: Cooldown, cargo: ShipCargo, modifiers: List(WaypointModifier), events: List(ShipConditionEvent), ) } fn resources_extracted_decoder() -> Decoder(ResourcesExtracted) { use extraction <- decode.field("extraction", extraction.decoder()) use cooldown <- decode.field("cooldown", cooldown.decoder()) use cargo <- decode.field("cargo", ship_cargo.decoder()) use modifiers <- decode.field( "modifiers", decode.list(waypoint_modifier.decoder()), ) use events <- decode.field( "events", decode.list(ship_condition_event.decoder()), ) decode.success(ResourcesExtracted( extraction:, cooldown:, cargo:, modifiers:, events:, )) } pub fn extract_resources( token: AgentToken, ship_symbol: ShipSymbol, ) -> ApiResponse(ResourcesExtracted) { let request = api.post( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/extract", ) use response <- api.try_send(request) case response.status { 201 -> api.parse_data_response(response, resources_extracted_decoder()) _ -> api.parse_error_response(response) } } pub fn extract_resources_with_survey( token: AgentToken, ship_symbol: ShipSymbol, survey: Survey, ) -> ApiResponse(ResourcesExtracted) { let request = api.post_json( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/extract/survey", survey.encode(survey), ) use response <- api.try_send(request) case response.status { 201 -> api.parse_data_response(response, resources_extracted_decoder()) _ -> api.parse_error_response(response) } } pub fn jettison_cargo( token: AgentToken, ship_symbol: ShipSymbol, trade_symbol: TradeSymbol, units: Int, ) -> ApiResponse(ShipCargo) { let request = api.post_json( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/jettison", json.object([ #("symbol", trade_symbol.encode(trade_symbol)), #("units", json.int(units)), ]), ) use response <- api.try_send(request) case response.status { 200 -> api.parse_data_response( response, decode.field("cargo", ship_cargo.decoder(), decode.success), ) _ -> api.parse_error_response(response) } } pub type ShipJumped { ShipJumped( nav: ShipNav, cooldown: Cooldown, transaction: MarketTransaction, agent: Agent, ) } pub fn jump_ship( token: AgentToken, ship_symbol: ShipSymbol, waypoint_symbol: WaypointSymbol, ) -> ApiResponse(ShipJumped) { let request = api.post_json( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/jump", json.object([#("waypointSymbol", waypoint_symbol.encode(waypoint_symbol))]), ) use response <- api.try_send(request) case response.status { 200 -> api.parse_data_response(response, { use nav <- decode.field("nav", ship_nav.decoder()) use cooldown <- decode.field("cooldown", cooldown.decoder()) use transaction <- decode.field( "transaction", market_transaction.decoder(), ) use agent <- decode.field("agent", agent.decoder()) decode.success(ShipJumped(nav:, cooldown:, transaction:, agent:)) }) _ -> api.parse_error_response(response) } } pub type Scan(data) { Scan(cooldown: Cooldown, data: List(data)) } fn scan_decoder(field: String, decoder: Decoder(data)) -> Decoder(Scan(data)) { use cooldown <- decode.field("cooldown", cooldown.decoder()) use data <- decode.field(field, decode.list(decoder)) decode.success(Scan(cooldown:, data:)) } pub fn scan_systems( token: AgentToken, ship_symbol: ShipSymbol, ) -> ApiResponse(Scan(ScannedSystem)) { let request = api.post( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/scan/systems", ) use response <- api.try_send(request) case response.status { 201 -> api.parse_data_response( response, scan_decoder("systems", scanned_system.decoder()), ) _ -> api.parse_error_response(response) } } pub fn scan_waypoints( token: AgentToken, ship_symbol: ShipSymbol, ) -> ApiResponse(Scan(ScannedWaypoint)) { let request = api.post( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/scan/waypoints", ) use response <- api.try_send(request) case response.status { 201 -> api.parse_data_response( response, scan_decoder("waypoints", scanned_waypoint.decoder()), ) _ -> api.parse_error_response(response) } } pub fn scan_ships( token: AgentToken, ship_symbol: ShipSymbol, ) -> ApiResponse(Scan(ScannedShip)) { let request = api.post( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/scan/ships", ) use response <- api.try_send(request) case response.status { 201 -> api.parse_data_response( response, scan_decoder("ships", scanned_ship.decoder()), ) _ -> api.parse_error_response(response) } } pub type ShipScrapped { ShipScrapped(agent: Agent, transaction: ScrapTransaction) } pub fn scrap_ship( token: AgentToken, ship_symbol: ShipSymbol, ) -> ApiResponse(ShipScrapped) { let request = api.post( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/scrap", ) use response <- api.try_send(request) case response.status { 200 -> api.parse_data_response(response, { use agent <- decode.field("agent", agent.decoder()) use transaction <- decode.field( "transaction", scrap_transaction.decoder(), ) decode.success(ShipScrapped(agent:, transaction:)) }) _ -> api.parse_error_response(response) } } pub fn get_scrap_ship( token: AgentToken, ship_symbol: ShipSymbol, ) -> ApiResponse(ScrapTransaction) { let request = api.get( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/scrap", ) use response <- api.try_send(request) case response.status { 200 -> api.parse_data_response( response, decode.field("transaction", scrap_transaction.decoder(), decode.success), ) _ -> api.parse_error_response(response) } } pub type ShipNavigated { ShipNavigated(nav: ShipNav, fuel: ShipFuel, events: List(ShipConditionEvent)) } pub fn navigate_ship( token: AgentToken, ship_symbol: ShipSymbol, waypoint_symbol: WaypointSymbol, ) -> ApiResponse(ShipNavigated) { let request = api.post_json( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/navigate", json.object([#("waypointSymbol", waypoint_symbol.encode(waypoint_symbol))]), ) use response <- api.try_send(request) case response.status { 200 -> api.parse_data_response(response, { use nav <- decode.field("nav", ship_nav.decoder()) use fuel <- decode.field("fuel", ship_fuel.decoder()) use events <- decode.field( "events", decode.list(ship_condition_event.decoder()), ) decode.success(ShipNavigated(nav:, fuel:, events:)) }) _ -> api.parse_error_response(response) } } pub type ShipWarped { ShipWarped(nav: ShipNav, fuel: ShipFuel, events: List(ShipConditionEvent)) } pub fn warp_ship( token: AgentToken, ship_symbol: ShipSymbol, waypoint_symbol: WaypointSymbol, ) -> ApiResponse(ShipWarped) { let request = api.post_json( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/warp", json.object([#("waypointSymbol", waypoint_symbol.encode(waypoint_symbol))]), ) use response <- api.try_send(request) case response.status { 200 -> api.parse_data_response(response, { use nav <- decode.field("nav", ship_nav.decoder()) use fuel <- decode.field("fuel", ship_fuel.decoder()) use events <- decode.field( "events", decode.list(ship_condition_event.decoder()), ) decode.success(ShipWarped(nav:, fuel:, events:)) }) _ -> api.parse_error_response(response) } } pub fn orbit_ship( token: AgentToken, ship_symbol: ShipSymbol, ) -> ApiResponse(ShipNav) { let request = api.post( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/orbit", ) use response <- api.try_send(request) case response.status { 200 -> api.parse_data_response( response, decode.field("nav", ship_nav.decoder(), decode.success), ) _ -> api.parse_error_response(response) } } pub type CargoPurchased { CargoPurchased(cargo: ShipCargo, transaction: MarketTransaction, agent: Agent) } pub fn purchase_cargo( token: AgentToken, ship_symbol: ShipSymbol, trade_symbol: TradeSymbol, ) -> ApiResponse(CargoPurchased) { let request = api.post_json( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/purchase", json.object([#("symbol", trade_symbol.encode(trade_symbol))]), ) use response <- api.try_send(request) case response.status { 201 -> api.parse_data_response(response, { use cargo <- decode.field("cargo", ship_cargo.decoder()) use transaction <- decode.field( "transaction", market_transaction.decoder(), ) use agent <- decode.field("agent", agent.decoder()) decode.success(CargoPurchased(cargo:, transaction:, agent:)) }) _ -> api.parse_error_response(response) } } pub type ShipRefined { ShipRefined( cargo: ShipCargo, cooldown: Cooldown, produced: List(RefinementYield), consumed: List(RefinementYield), ) } pub fn refine_ship( token: AgentToken, ship_symbol: ShipSymbol, produce: RefinementProduce, ) -> ApiResponse(ShipRefined) { let request = api.post_json( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/refine", json.object([#("produce", refinement_produce.encode(produce))]), ) use response <- api.try_send(request) case response.status { 201 -> api.parse_data_response(response, { use cargo <- decode.field("cargo", ship_cargo.decoder()) use cooldown <- decode.field("cooldown", cooldown.decoder()) use produced <- decode.field( "produced", decode.list(refinement_yield.decoder()), ) use consumed <- decode.field( "consumed", decode.list(refinement_yield.decoder()), ) decode.success(ShipRefined(cargo:, cooldown:, produced:, consumed:)) }) _ -> api.parse_error_response(response) } } pub type ShipRefueled { ShipRefueled( agent: Agent, fuel: ShipFuel, cargo: ShipCargo, transaction: MarketTransaction, ) } pub fn refuel_ship( token: AgentToken, ship_symbol: ShipSymbol, units: Option(Int), from_cargo: Option(Bool), ) -> ApiResponse(ShipRefueled) { let request = api.post_json( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/refuel", json.object([ #("units", json.nullable(units, json.int)), #("fromCargo", json.nullable(from_cargo, json.bool)), ]), ) use response <- api.try_send(request) case response.status { 200 -> api.parse_data_response(response, { use agent <- decode.field("agent", agent.decoder()) use fuel <- decode.field("fuel", ship_fuel.decoder()) use cargo <- decode.field("cargo", ship_cargo.decoder()) use transaction <- decode.field( "transaction", market_transaction.decoder(), ) decode.success(ShipRefueled(agent:, fuel:, cargo:, transaction:)) }) _ -> api.parse_error_response(response) } } pub type ShipRepaired { ShipRepaired(agent: Agent, ship: Ship, transaction: RepairTransaction) } pub fn repair_ship( token: AgentToken, ship_symbol: ShipSymbol, ) -> ApiResponse(ShipRepaired) { let request = api.post( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/repair", ) use response <- api.try_send(request) case response.status { 200 -> api.parse_data_response(response, { use agent <- decode.field("agent", agent.decoder()) use ship <- decode.field("ship", ship.decoder()) use transaction <- decode.field( "transaction", repair_transaction.decoder(), ) decode.success(ShipRepaired(agent:, ship:, transaction:)) }) _ -> api.parse_error_response(response) } } pub fn get_repair_ship( token: AgentToken, ship_symbol: ShipSymbol, ) -> ApiResponse(RepairTransaction) { let request = api.get( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/repair", ) use response <- api.try_send(request) case response.status { 200 -> api.parse_data_response( response, decode.field( "transaction", repair_transaction.decoder(), decode.success, ), ) _ -> api.parse_error_response(response) } } pub type CargoSold { CargoSold(cargo: ShipCargo, transaction: MarketTransaction, agent: Agent) } pub fn sell_cargo( token: AgentToken, ship_symbol: ShipSymbol, trade_symbol: TradeSymbol, units: Int, ) -> ApiResponse(CargoSold) { let request = api.post_json( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/sell", json.object([ #("symbol", trade_symbol.encode(trade_symbol)), #("units", json.int(units)), ]), ) use response <- api.try_send(request) case response.status { 201 -> api.parse_data_response(response, { use cargo <- decode.field("cargo", ship_cargo.decoder()) use transaction <- decode.field( "transaction", market_transaction.decoder(), ) use agent <- decode.field("agent", agent.decoder()) decode.success(CargoSold(cargo:, transaction:, agent:)) }) _ -> api.parse_error_response(response) } } pub type ResourcesSiphoned { ResourcesSiphoned( siphon: Siphon, cooldown: Cooldown, cargo: ShipCargo, events: List(ShipConditionEvent), ) } pub fn siphon_resources( token: AgentToken, ship_symbol: ShipSymbol, ) -> ApiResponse(ResourcesSiphoned) { let request = api.post( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/siphon", ) use response <- api.try_send(request) case response.status { 201 -> api.parse_data_response(response, { use siphon <- decode.field("siphon", siphon.decoder()) use cooldown <- decode.field("cooldown", cooldown.decoder()) use cargo <- decode.field("cargo", ship_cargo.decoder()) use events <- decode.field( "events", decode.list(ship_condition_event.decoder()), ) decode.success(ResourcesSiphoned(siphon:, cooldown:, cargo:, events:)) }) _ -> api.parse_error_response(response) } } pub type SurveyCreated { SurveyCreated(cooldown: Cooldown, surveys: List(Survey)) } pub fn create_survey( token: AgentToken, ship_symbol: ShipSymbol, ) -> ApiResponse(SurveyCreated) { let request = api.post( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/survey", ) use response <- api.try_send(request) case response.status { 201 -> api.parse_data_response(response, { use cooldown <- decode.field("cooldown", cooldown.decoder()) use surveys <- decode.field("surveys", decode.list(survey.decoder())) decode.success(SurveyCreated(cooldown:, surveys:)) }) _ -> api.parse_error_response(response) } } pub type CargoTransferred { CargoTransferred(cargo: ShipCargo, target_cargo: ShipCargo) } pub fn transfer_cargo( token: AgentToken, ship_symbol: ShipSymbol, trade_symbol: TradeSymbol, units: Int, target_ship_symbol: ShipSymbol, ) -> ApiResponse(CargoTransferred) { let request = api.post_json( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/transfer", json.object([ #("tradeSymbol", trade_symbol.encode(trade_symbol)), #("units", json.int(units)), #("shipSymbol", ship_symbol.encode(target_ship_symbol)), ]), ) use response <- api.try_send(request) case response.status { 200 -> api.parse_data_response(response, { use cargo <- decode.field("cargo", ship_cargo.decoder()) use target_cargo <- decode.field("targetCargo", ship_cargo.decoder()) decode.success(CargoTransferred(cargo:, target_cargo:)) }) _ -> api.parse_error_response(response) } } pub fn get_ship_cargo( token: AgentToken, ship_symbol: ShipSymbol, ) -> ApiResponse(ShipCargo) { let request = api.get( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/cargo", ) use response <- api.try_send(request) case response.status { 200 -> api.parse_data_response(response, ship_cargo.decoder()) _ -> api.parse_error_response(response) } } pub fn get_ship_modules( token: AgentToken, ship_symbol: ShipSymbol, ) -> ApiResponse(List(ShipModule)) { let request = api.get( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/modules", ) use response <- api.try_send(request) case response.status { 200 -> api.parse_data_response(response, decode.list(ship_module.decoder())) _ -> api.parse_error_response(response) } } pub type ShipModuleInstalled { ShipModuleInstalled( agent: Agent, modules: List(ShipModule), cargo: ShipCargo, transaction: ShipModificationTransaction, ) } pub fn install_ship_module( token: AgentToken, ship_symbol: ShipSymbol, module_symbol: ModuleSymbol, ) -> ApiResponse(ShipModuleInstalled) { let request = api.post_json( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/modules/install", json.object([#("symbol", module_symbol.encode(module_symbol))]), ) use response <- api.try_send(request) case response.status { 201 -> api.parse_data_response(response, { use agent <- decode.field("agent", agent.decoder()) use modules <- decode.field( "modules", decode.list(ship_module.decoder()), ) use cargo <- decode.field("cargo", ship_cargo.decoder()) use transaction <- decode.field( "transaction", ship_modification_transaction.decoder(), ) decode.success(ShipModuleInstalled( agent:, modules:, cargo:, transaction:, )) }) _ -> api.parse_error_response(response) } } pub type ShipModuleRemoved { ShipModuleRemoved( agent: Agent, modules: List(ShipModule), cargo: ShipCargo, transaction: ShipModificationTransaction, ) } pub fn remove_ship_module( token: AgentToken, ship_symbol: ShipSymbol, module_symbol: ModuleSymbol, ) -> ApiResponse(ShipModuleRemoved) { let request = api.post_json( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/modules/remove", json.object([#("symbol", module_symbol.encode(module_symbol))]), ) use response <- api.try_send(request) case response.status { 201 -> api.parse_data_response(response, { use agent <- decode.field("agent", agent.decoder()) use modules <- decode.field( "modules", decode.list(ship_module.decoder()), ) use cargo <- decode.field("cargo", ship_cargo.decoder()) use transaction <- decode.field( "transaction", ship_modification_transaction.decoder(), ) decode.success(ShipModuleRemoved(agent:, modules:, cargo:, transaction:)) }) _ -> api.parse_error_response(response) } } pub fn get_ship_mounts( token: AgentToken, ship_symbol: ShipSymbol, ) -> ApiResponse(List(ShipMount)) { let request = api.get( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/mounts", ) use response <- api.try_send(request) case response.status { 200 -> api.parse_data_response(response, decode.list(ship_mount.decoder())) _ -> api.parse_error_response(response) } } pub type ShipMountInstalled { ShipMountInstalled( agent: Agent, mounts: List(ShipMount), cargo: ShipCargo, transaction: ShipModificationTransaction, ) } pub fn install_ship_mount( token: AgentToken, ship_symbol: ShipSymbol, mount_symbol: MountSymbol, ) -> ApiResponse(ShipMountInstalled) { let request = api.post_json( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/mounts/install", json.object([#("symbol", mount_symbol.encode(mount_symbol))]), ) use response <- api.try_send(request) case response.status { 201 -> api.parse_data_response(response, { use agent <- decode.field("agent", agent.decoder()) use mounts <- decode.field("mounts", decode.list(ship_mount.decoder())) use cargo <- decode.field("cargo", ship_cargo.decoder()) use transaction <- decode.field( "transaction", ship_modification_transaction.decoder(), ) decode.success(ShipMountInstalled(agent:, mounts:, cargo:, transaction:)) }) _ -> api.parse_error_response(response) } } pub type ShipMountRemoved { ShipMountRemoved( agent: Agent, mounts: List(ShipMount), cargo: ShipCargo, transaction: ShipModificationTransaction, ) } pub fn remove_ship_mount( token: AgentToken, ship_symbol: ShipSymbol, mount_symbol: MountSymbol, ) -> ApiResponse(ShipMountRemoved) { let request = api.post_json( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/mounts/remove", json.object([#("symbol", mount_symbol.encode(mount_symbol))]), ) use response <- api.try_send(request) case response.status { 201 -> api.parse_data_response(response, { use agent <- decode.field("agent", agent.decoder()) use mounts <- decode.field("mounts", decode.list(ship_mount.decoder())) use cargo <- decode.field("cargo", ship_cargo.decoder()) use transaction <- decode.field( "transaction", ship_modification_transaction.decoder(), ) decode.success(ShipMountRemoved(agent:, mounts:, cargo:, transaction:)) }) _ -> api.parse_error_response(response) } } pub fn get_ship_nav( token: AgentToken, ship_symbol: ShipSymbol, ) -> ApiResponse(ShipNav) { let request = api.get( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/nav", ) use response <- api.try_send(request) case response.status { 200 -> api.parse_data_response(response, ship_nav.decoder()) _ -> api.parse_error_response(response) } } pub type ShipNavPatched { ShipNavPatched(nav: ShipNav, fuel: ShipFuel, events: List(ShipConditionEvent)) } pub fn patch_ship_nav( token: AgentToken, ship_symbol: ShipSymbol, flight_mode: ShipNavFlightMode, ) -> ApiResponse(ShipNavPatched) { let request = api.patch_json( AgentAuth(token), "/my/ships/" <> ship_symbol.to_string(ship_symbol) <> "/nav", json.object([#("flightMode", ship_nav_flight_mode.encode(flight_mode))]), ) use response <- api.try_send(request) case response.status { 200 -> api.parse_data_response(response, { use nav <- decode.field("nav", ship_nav.decoder()) use fuel <- decode.field("fuel", ship_fuel.decoder()) use events <- decode.field( "events", decode.list(ship_condition_event.decoder()), ) decode.success(ShipNavPatched(nav:, fuel:, events:)) }) _ -> api.parse_error_response(response) } }