handle errors for exit

This commit is contained in:
Max Bradbury 2020-04-29 20:43:49 +01:00
parent 5bfcc9ab4c
commit e760027ae4
2 changed files with 45 additions and 33 deletions

View File

@ -1,5 +1,7 @@
use crate::{from_base36, Position, ToBase36}; use crate::{from_base36, Position, ToBase36};
use std::str::FromStr; use std::str::FromStr;
use std::error::Error;
use std::fmt;
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]
pub enum Transition { pub enum Transition {
@ -58,32 +60,37 @@ pub struct Exit {
pub effect: Transition, pub effect: Transition,
} }
impl From<String> for Exit { impl Error for Exit {}
#[inline]
fn from(string: String) -> Exit {
// e.g. "EXT 6,4 0 10,12 FX fade_w"
let room_position_effect: Vec<&str> = string.split_whitespace().collect();
let room_id = from_base36(room_position_effect[0]);
let position = Position::from_str(room_position_effect[1]).unwrap();
let effect = if room_position_effect.len() == 4 { impl FromStr for Exit {
Transition::from(room_position_effect[3]) type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut parts = s.split_whitespace();
let room_id = from_base36(parts.next().unwrap());
let position = Position::from_str(parts.next().unwrap());
if position.is_err() {
return Err("Invalid position for exit".to_string());
}
let position = position.unwrap();
let effect = if parts.next().is_some() {
Transition::from(parts.next().unwrap())
} else { } else {
Transition::None Transition::None
}; };
Exit { Ok(Exit { room_id, position, effect })
room_id,
position,
effect,
}
} }
} }
impl ToString for Exit { impl fmt::Display for Exit {
#[inline] #[inline]
fn to_string(&self) -> String { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
format!( write!(
f,
"{} {}{}", "{} {}{}",
self.room_id.to_base36(), self.room_id.to_base36(),
self.position.to_string(), self.position.to_string(),
@ -96,11 +103,12 @@ impl ToString for Exit {
mod test { mod test {
use crate::exit::{Transition, Exit}; use crate::exit::{Transition, Exit};
use crate::position::Position; use crate::position::Position;
use std::str::FromStr;
#[test] #[test]
fn test_exit_from_string() { fn test_exit_from_string() {
assert_eq!( assert_eq!(
Exit::from("a 12,13".to_string()), Exit::from_str("a 12,13").unwrap(),
Exit { Exit {
room_id: 10, room_id: 10,
position: Position { x: 12, y: 13 }, position: Position { x: 12, y: 13 },
@ -112,7 +120,7 @@ mod test {
#[test] #[test]
fn test_exit_from_string_with_fx() { fn test_exit_from_string_with_fx() {
assert_eq!( assert_eq!(
Exit::from("a 12,13 FX slide_u".to_string()), Exit::from_str("a 12,13 FX slide_u").unwrap(),
Exit { Exit {
room_id: 10, room_id: 10,
position: Position { x: 12, y: 13 }, position: Position { x: 12, y: 13 },
@ -128,8 +136,7 @@ mod test {
room_id: 8, room_id: 8,
position: Position { x: 5, y: 6 }, position: Position { x: 5, y: 6 },
effect: Transition::None effect: Transition::None
} }.to_string(),
.to_string(),
"8 5,6".to_string() "8 5,6".to_string()
); );
} }
@ -141,8 +148,7 @@ mod test {
room_id: 8, room_id: 8,
position: Position { x: 5, y: 6 }, position: Position { x: 5, y: 6 },
effect: Transition::FadeToWhite effect: Transition::FadeToWhite
} }.to_string(),
.to_string(),
"8 5,6 FX fade_w".to_string() "8 5,6 FX fade_w".to_string()
); );
} }

View File

@ -84,18 +84,24 @@ impl From<String> for Room {
if position.is_ok() { if position.is_ok() {
let position = position.unwrap(); let position = position.unwrap();
let exit = Exit::from(format!("{} {}", parts[1], parts[2])); let exit = Exit::from_str(
let mut transition = None; &format!("{} {}", parts[1], parts[2])
let mut dialogue_id = None; );
let chunks = parts[3..].chunks(2);
for chunk in chunks { if exit.is_ok() {
if chunk[0] == "FX" { let exit = exit.unwrap();
transition = Some(Transition::from(chunk[1])); let mut transition = None;
} else if chunk[0] == "DLG" { let mut dialogue_id = None;
dialogue_id = Some(chunk[1].to_string()); let chunks = parts[3..].chunks(2);
for chunk in chunks {
if chunk[0] == "FX" {
transition = Some(Transition::from(chunk[1]));
} else if chunk[0] == "DLG" {
dialogue_id = Some(chunk[1].to_string());
}
} }
exits.push(ExitInstance { position, exit, transition, dialogue_id });
} }
exits.push(ExitInstance { position, exit, transition, dialogue_id });
} }
} else if last_line.starts_with("END") { } else if last_line.starts_with("END") {
let last_line = last_line.replace("END ", ""); let last_line = last_line.replace("END ", "");