From b9d6a42cb15a0cf3e80885e8aa5cbc4085b05791 Mon Sep 17 00:00:00 2001 From: Micah Date: Mon, 11 Sep 2023 15:55:17 -0700 Subject: [PATCH] Implement FromStr for TerrainMaterials (#354) Closes #353. This also modifies `MaterialColorsError` to be a generalized error for both `MaterialColors` and `TerrainColors`. This is technically a breaking change because the enum is publicly exposed, but I don't think it will seriously impact anyone beyond adding a new variant to the enum. --- rbx_types/CHANGELOG.md | 4 ++++ rbx_types/src/material_colors.rs | 34 ++++++++++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/rbx_types/CHANGELOG.md b/rbx_types/CHANGELOG.md index 41d87dcda..d0bc43a38 100644 --- a/rbx_types/CHANGELOG.md +++ b/rbx_types/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased Changes +* Implement `FromStr` for `TerrainMaterials`. ([#354]) + +[#354]: https://github.com/rojo-rbx/rbx-dom/pull/354 + ## 1.6.0 (2023-08-09) * Added support for `UniqueId` values. ([#271]) * Changed `BinaryString`'s non-human readable serde implementation to be identical to `Vec`. ([#276]) diff --git a/rbx_types/src/material_colors.rs b/rbx_types/src/material_colors.rs index 39be9b5c7..8e9fed271 100644 --- a/rbx_types/src/material_colors.rs +++ b/rbx_types/src/material_colors.rs @@ -1,4 +1,4 @@ -use std::collections::BTreeMap; +use std::{collections::BTreeMap, str::FromStr}; use thiserror::Error; @@ -88,7 +88,7 @@ where } } -/// An error that can occur when deserializing MaterialColors. +/// An error that can occur when deserializing or working with MaterialColors and TerrainMaterials. #[derive(Debug, Error)] pub enum MaterialColorsError { /// The `MaterialColors` blob was the wrong number of bytes. @@ -96,6 +96,10 @@ pub enum MaterialColorsError { "MaterialColors blob was the wrong length (expected it to be 69 bytes, it was {0} bytes)" )] WrongLength(usize), + /// The argument provided to `from_str` did not correspond to a known + /// TerrainMaterial. + #[error("cannot convert `{0}` into TerrainMaterial")] + UnknownMaterial(String), } /// Constructs an enum named `TerrainMaterials` for all values contained in @@ -136,6 +140,18 @@ macro_rules! material_colors { } } } + + impl FromStr for TerrainMaterials { + type Err = CrateError; + + fn from_str(s: &str) -> Result { + match s {$( + stringify!($name) => Ok(Self::$name), + )* + _ => Err(MaterialColorsError::UnknownMaterial(s.to_string()).into()), + } + } + } }; } @@ -265,4 +281,18 @@ mod test { assert_eq!(blob, "AAAAAAAAAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5Ojs8PT4/"); } + + #[test] + fn from_str_materials() { + assert!(TerrainMaterials::from_str("Grass").is_ok()); + assert!(TerrainMaterials::from_str("Concrete").is_ok()); + assert!(TerrainMaterials::from_str("Rock").is_ok()); + assert!(TerrainMaterials::from_str("Asphalt").is_ok()); + assert!(TerrainMaterials::from_str("Salt").is_ok()); + assert!(TerrainMaterials::from_str("Pavement").is_ok()); + + assert!(TerrainMaterials::from_str("A name I am certain Roblox will never add").is_err()); + // `from_str` is case-sensitive + assert!(TerrainMaterials::from_str("gRaSs").is_err()); + } }