Drop NonEmpty for inline guards
The wrapper had no downstream consumer of its guarantee; is_empty
guards in Spec::from_lua keep the check and name the field.
Assisted-by: GLM-5.3 via pi
diff --git a/src/spec.rs b/src/spec.rs
index 01a8569..27fbd11 100644
--- a/src/spec.rs
+++ b/src/spec.rs
@@ -48,28 +48,6 @@ impl<'de> Deserialize<'de> for NonEmptyString {
}
}
-/// A non-empty sequence of values, rejected at deserialization time.
-#[derive(Debug)]
-pub(crate) struct NonEmpty<T>(Vec<T>);
-
-impl<T> NonEmpty<T> {
- // Consumed once running configs lands.
- #[allow(dead_code)]
- pub(crate) fn as_slice(&self) -> &[T] {
- &self.0
- }
-}
-
-impl<'de, T: Deserialize<'de>> Deserialize<'de> for NonEmpty<T> {
- fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
- let items = Vec::<T>::deserialize(deserializer)?;
- if items.is_empty() {
- return Err(serde::de::Error::custom("must not be empty"));
- }
- Ok(NonEmpty(items))
- }
-}
-
/// A flow: its name from the config and the Lua function to call when
/// the parallax runs.
#[derive(Debug)]
@@ -146,7 +124,7 @@ impl FromLua for Baseline {
#[serde(deny_unknown_fields)]
#[allow(dead_code)] // read by tests now, by the runner once run lands
pub(crate) struct Schema {
- pub(crate) viewports: NonEmpty<(NonEmptyString, NonZeroU32, NonZeroU32)>,
+ pub(crate) viewports: Vec<(NonEmptyString, NonZeroU32, NonZeroU32)>,
pub(crate) server: Server,
pub(crate) baseline: Option<IgnoredAny>,
@@ -160,7 +138,7 @@ pub(crate) struct Schema {
#[serde(deny_unknown_fields)]
#[allow(dead_code)] // read by tests now, by the runner once run lands
pub(crate) struct Server {
- pub(crate) cmd: NonEmpty<String>,
+ pub(crate) cmd: Vec<String>,
#[serde(default = "default_timeout")]
pub(crate) timeout: f64,
@@ -193,6 +171,12 @@ impl FromLua for Spec {
other => other,
}
})?;
+ if schema.viewports.is_empty() {
+ return Err(mlua::Error::runtime("viewports must not be empty"));
+ }
+ if schema.server.cmd.is_empty() {
+ return Err(mlua::Error::runtime("server.cmd must not be empty"));
+ }
let table = Table::from_lua(value, lua)?;
let flows = Flows::from_lua(table.get("flows")?, lua)?;
let baseline = Baseline::from_lua(table.get("baseline")?, lua)?;
@@ -239,7 +223,7 @@ mod tests {
fn accepts_a_valid_config() {
with_spec(&format!("{VIEWPORTS}, {SERVER}, {FLOWS}"), |lua, table| {
let spec = spec(lua, table).expect("valid config");
- assert_eq!(spec.schema.viewports.as_slice().len(), 1);
+ assert_eq!(spec.schema.viewports.len(), 1);
assert_eq!(spec.flows.as_slice().len(), 1);
assert_eq!(spec.flows.as_slice()[0].name.as_str(), "flow");
assert!(spec.baseline.as_function().is_none());
@@ -297,7 +281,7 @@ mod tests {
fn rejects_empty_or_unnamed_viewports() {
assert_message(
&format!("viewports = {{}}, {SERVER}, {FLOWS}"),
- "must not be empty",
+ "viewports must not be empty",
);
assert_message(
&format!(r#"viewports = {{{{"desktop", 0, 900}}}}, {SERVER}, {FLOWS}"#),
@@ -313,7 +297,7 @@ mod tests {
fn rejects_an_empty_server_cmd() {
assert_message(
&format!("{VIEWPORTS}, server = {{cmd = {{}}}}, {FLOWS}"),
- "must not be empty",
+ "server.cmd must not be empty",
);
}