diff --git a/map/src/format.rs b/map/src/format.rs index b466c807..d54b0ef7 100644 --- a/map/src/format.rs +++ b/map/src/format.rs @@ -239,31 +239,33 @@ pub struct MapItemLayerV1TilemapExtraRace { pub data: i32, } impl MapItemLayerV1TilemapExtraRace { - pub fn offset(version: i32, flags: u32) -> Option { - let offset = match version { - 2 => MapItemLayerV1TilemapV2::sum_len(), - 3 => MapItemLayerV1TilemapV3::sum_len(), - _ => return None, + pub fn offset(version: i32, flags: i32) + -> Result + { + let offset = if version < 2 { + return Err(LayerTilemapError::InvalidVersion(version)) + } else if version == 2 { + MapItemLayerV1TilemapV2::sum_len() + } else { + MapItemLayerV1TilemapV3::sum_len() }; - Some(offset + match flags { + Ok(offset + match flags as u32 { TILELAYERFLAG_TELEPORT => 0, TILELAYERFLAG_SPEEDUP => 1, TILELAYERFLAG_FRONT => 2, TILELAYERFLAG_SWITCH => 3, TILELAYERFLAG_TUNE => 4, - _ => return None, + _ => return Err(LayerTilemapError::InvalidFlags(flags)), }) } - pub fn from_slice(slice: &[i32], version: i32, flags: u32) - -> Option<&MapItemLayerV1TilemapExtraRace> + pub fn from_slice(slice: &[i32], version: i32, flags: i32) + -> Result<&MapItemLayerV1TilemapExtraRace, LayerTilemapError> { - let offset = unwrap_or_return!( - MapItemLayerV1TilemapExtraRace::offset(version, flags), None - ); + let offset = MapItemLayerV1TilemapExtraRace::offset(version, flags)?; if slice.len() <= offset { - return None; + return Err(LayerTilemapError::TooShort(slice.len())); } - Some(&(unsafe { common::slice::transmute(slice) })[offset]) + Ok(&(unsafe { common::slice::transmute(slice) })[offset]) } } diff --git a/map/src/generate_format.py b/map/src/generate_format.py index 05ce4bef..97606527 100644 --- a/map/src/generate_format.py +++ b/map/src/generate_format.py @@ -291,31 +291,33 @@ pub data: i32, } impl MapItemLayerV1TilemapExtraRace { - pub fn offset(version: i32, flags: u32) -> Option { - let offset = match version { - 2 => MapItemLayerV1TilemapV2::sum_len(), - 3 => MapItemLayerV1TilemapV3::sum_len(), - _ => return None, + pub fn offset(version: i32, flags: i32) + -> Result + { + let offset = if version < 2 { + return Err(LayerTilemapError::InvalidVersion(version)) + } else if version == 2 { + MapItemLayerV1TilemapV2::sum_len() + } else { + MapItemLayerV1TilemapV3::sum_len() }; - Some(offset + match flags { + Ok(offset + match flags as u32 { TILELAYERFLAG_TELEPORT => 0, TILELAYERFLAG_SPEEDUP => 1, TILELAYERFLAG_FRONT => 2, TILELAYERFLAG_SWITCH => 3, TILELAYERFLAG_TUNE => 4, - _ => return None, + _ => return Err(LayerTilemapError::InvalidFlags(flags)), }) } - pub fn from_slice(slice: &[i32], version: i32, flags: u32) - -> Option<&MapItemLayerV1TilemapExtraRace> + pub fn from_slice(slice: &[i32], version: i32, flags: i32) + -> Result<&MapItemLayerV1TilemapExtraRace, LayerTilemapError> { - let offset = unwrap_or_return!( - MapItemLayerV1TilemapExtraRace::offset(version, flags), None - ); + let offset = MapItemLayerV1TilemapExtraRace::offset(version, flags)?; if slice.len() <= offset { - return None; + return Err(LayerTilemapError::TooShort(slice.len())); } - Some(&(unsafe { common::slice::transmute(slice) })[offset]) + Ok(&(unsafe { common::slice::transmute(slice) })[offset]) } } diff --git a/map/src/reader.rs b/map/src/reader.rs index bee98916..77cf55f2 100644 --- a/map/src/reader.rs +++ b/map/src/reader.rs @@ -331,18 +331,20 @@ impl LayerTilemap { use format::ColorComponent::*; use format::LayerTilemapError::*; - fn extra(raw: &[i32], version: i32, flags: u32, too_short: TS) + fn extra(raw: &[i32], version: i32, flags: i32, too_short: TS) -> Result<&format::MapItemLayerV1TilemapExtraRace, format::LayerTilemapError> where TS: FnOnce(usize) -> format::LayerTilemapError { format::MapItemLayerV1TilemapExtraRace::from_slice(raw, version, flags) - .ok_or_else(|| too_short(raw.len())) + .map_err(|e| match e { + TooShort(_) => too_short(raw.len()), + other_err => other_err, + }) } let v0 = format::MapItemLayerV1CommonV0::mandatory(raw, TooShort, InvalidVersion)?; let v2 = format::MapItemLayerV1TilemapV2::mandatory(raw, TooShortV2, InvalidVersion)?; let v3 = format::MapItemLayerV1TilemapV3::optional(raw, TooShortV3)?; - let flags = v2.flags as u32; // TODO: Standard settings for game group. let color = Color { @@ -364,7 +366,7 @@ impl LayerTilemap { let image = get_index_opt(v2.image, image_indices, InvalidImageIndex)?; let data = get_index(v2.data, data_indices.clone(), InvalidDataIndex)?; let mut normal = false; - let type_ = match flags { + let type_ = match v2.flags as u32 { 0 => { normal = true; LayerTilemapType::Normal(LayerTilemapNormal { @@ -380,7 +382,7 @@ impl LayerTilemap { format::TILELAYERFLAG_TELEPORT => { LayerTilemapType::RaceTeleport( get_index( - extra(raw, v0.version, flags, TooShortRaceTeleport)?.data, + extra(raw, v0.version, v2.flags, TooShortRaceTeleport)?.data, data_indices.clone(), InvalidRaceTeleportDataIndex, )?, @@ -390,7 +392,7 @@ impl LayerTilemap { format::TILELAYERFLAG_SPEEDUP => { LayerTilemapType::RaceSpeedup( get_index( - extra(raw, v0.version, flags, TooShortRaceSpeedup)?.data, + extra(raw, v0.version, v2.flags, TooShortRaceSpeedup)?.data, data_indices.clone(), InvalidRaceSpeedupDataIndex, )?, @@ -400,7 +402,7 @@ impl LayerTilemap { format::TILELAYERFLAG_FRONT => { LayerTilemapType::DdraceFront( get_index( - extra(raw, v0.version, flags, TooShortDdraceFront)?.data, + extra(raw, v0.version, v2.flags, TooShortDdraceFront)?.data, data_indices.clone(), InvalidDdraceFrontDataIndex, )?, @@ -410,7 +412,7 @@ impl LayerTilemap { format::TILELAYERFLAG_SWITCH => { LayerTilemapType::DdraceSwitch( get_index( - extra(raw, v0.version, flags, TooShortDdraceSwitch)?.data, + extra(raw, v0.version, v2.flags, TooShortDdraceSwitch)?.data, data_indices.clone(), InvalidDdraceSwitchDataIndex, )?, @@ -420,7 +422,7 @@ impl LayerTilemap { format::TILELAYERFLAG_TUNE => { LayerTilemapType::DdraceTune( get_index( - extra(raw, v0.version, flags, TooShortDdraceTune)?.data, + extra(raw, v0.version, v2.flags, TooShortDdraceTune)?.data, data_indices.clone(), InvalidDdraceTuneDataIndex, )?,