use std::collections::{BTreeMap, HashMap}; use std::error::Error; use std::io; use std::io::Read; use serde_derive::Deserialize; use serde_json::Value; #[derive(Debug, Deserialize)] struct MudletMap { /// area id id: i64, /// area name name: String, /// rooms rooms: Vec, #[serde(flatten)] _extra: HashMap, } #[derive(Debug, Deserialize)] struct MudletRoom { /// exits exits: Vec, /// room number id: i64, /// room name name: String, /// user data userData: MudletUserData, #[serde(flatten)] _extra: HashMap, } #[derive(Debug, Deserialize)] struct MudletExit { /// connected room exitId: i64, /// direction name: String, #[serde(flatten)] _extra: HashMap, } #[derive(Debug, Deserialize)] struct MudletUserData { /// room description description: String, /// zone name zone: String, #[serde(flatten)] _extra: HashMap, } #[derive(Debug)] struct TinTinRoom { /// room number vnum: i64, /// flags flags: i64, /// color color: String, /// room name name: String, /// room symbol symbol: char, /// room description desc: String, /// area that room is in area: String, /// notes note: String, /// type of terrain terrain: String, /// extra data data: String, /// movement cost weight: f64, /// room id id: String, /// exits exits: Vec, } #[derive(Debug)] struct TinTinExit { /// vnum vnum: i64, /// exit name name: String, /// command to use the exit cmd: String, /// exit direction dir: i8, /// exit flags flags: i64, /// extra data data: String, /// movement cost? weight: f64, /// exit color color: String, /// decay? decay: f64, } fn main() -> Result<(), Box> { let mut buffer = String::new(); let mut stdin = io::stdin(); stdin.read_to_string(&mut buffer)?; let mudlet_map: MudletMap = serde_json::from_str(&buffer)?; let mut tintin_rooms: BTreeMap = BTreeMap::new(); for mudlet_room in mudlet_map.rooms { let mut tintin_exits: Vec = Vec::new(); for mudlet_exit in mudlet_room.exits { let (dir_num, dir_short) = match mudlet_exit.name.as_str() { "north" => (1, 'n'), "east" => (2, 'e'), "south" => (4, 's'), "west" => (8, 'w'), "up" => (16, 'u'), "down" => (32, 'd'), _ => panic!("Unknown exit: {}", mudlet_exit.name), }; let tintin_exit = TinTinExit { vnum: mudlet_exit.exitId, name: dir_short.into(), cmd: dir_short.into(), dir: dir_num, flags: 0, data: String::new(), weight: 1.0, color: String::new(), decay: 0.0, }; tintin_exits.push(tintin_exit); } let tintin_room = TinTinRoom { vnum: mudlet_room.id, flags: 0, color: String::new(), name: mudlet_room.name, symbol: ' ', desc: mudlet_room.userData.description.replace("\n", " ").replace (" ", " "), area: mudlet_room.userData.zone, note: String::new(), terrain: String::new(), data: String::new(), weight: 1.0, id: String::new(), exits: tintin_exits, }; tintin_rooms.insert(tintin_room.vnum, tintin_room); } for (vnum, room) in tintin_rooms { println!("R {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}}", vnum, room.flags, room.color, room.name, room.symbol, room.desc, room.area, room.note, room.terrain, room.data, room.weight, room.id); for exit in room.exits { println!("E {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}}", exit.vnum, exit.name, exit.cmd, exit.dir, exit.flags, exit.data, exit.weight, exit.color, exit.decay); } println!(); } Ok(()) }