diff --git a/src/game.rs b/src/game.rs index e143408..6d6184e 100644 --- a/src/game.rs +++ b/src/game.rs @@ -221,7 +221,13 @@ impl Game { sprites.push(sprite); } } else if segment.starts_with("ITM ") { - items.push(Item::from(segment)); + let result = Item::from_str(&segment); + + if let Ok(item) = result { + items.push(item); + } else { + warnings.push(result.unwrap_err()); + } } else if segment.starts_with("DLG ") { let result = Dialogue::from_str(&segment); diff --git a/src/item.rs b/src/item.rs index 4b083e3..641ff71 100644 --- a/src/item.rs +++ b/src/item.rs @@ -1,5 +1,6 @@ use crate::{optional_data_line, AnimationFrames, Image}; use crate::image::animation_frames_from_str; +use std::fmt; #[derive(Clone, Debug, Eq, PartialEq)] pub struct Item { @@ -22,11 +23,13 @@ impl Item { fn colour_line(&self) -> String { optional_data_line("COL", self.colour_id.as_ref()) } -} -impl From for Item { - fn from(string: String) -> Item { - let mut lines: Vec<&str> = string.lines().collect(); + pub fn from_str(str: &str) -> Result { + let mut lines: Vec<&str> = str.lines().collect(); + + if lines.is_empty() || !lines[0].starts_with("ITM ") { + return Err(crate::Error::Item); + } let id = lines[0].replace("ITM ", ""); let mut name = None; @@ -52,19 +55,14 @@ impl From for Item { &lines[1..].join("\n") ); - Item { - id, - name, - animation_frames, - dialogue_id, - colour_id, - } + Ok(Item { id, name, animation_frames, dialogue_id, colour_id }) } } -impl ToString for Item { - fn to_string(&self) -> String { - format!( +impl fmt::Display for Item { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, "ITM {}\n{}{}{}{}", self.id, self.animation_frames.to_string(), @@ -81,7 +79,7 @@ mod test { #[test] fn item_from_string() { - let output = Item::from(include_str!("test-resources/item").to_string()); + let output = Item::from_str(include_str!("test-resources/item")).unwrap(); let expected = mock::item(); assert_eq!(output, expected); }