extract helper functions for validation

This commit is contained in:
Niko Matsakis 2022-08-02 14:22:45 +03:00
parent db75a1a510
commit f2649ee503
3 changed files with 38 additions and 21 deletions

View file

@ -45,13 +45,7 @@ impl EntityLike {
}
fn validate_entity(&self) -> syn::Result<()> {
// Require that entities are structs for now.
if !self.has_named_fields() {
return Err(syn::Error::new(
self.id_ident().span(),
"entities must be structs with named fields",
));
}
self.require_named_fields("entity")?;
Ok(())
}

View file

@ -201,6 +201,42 @@ impl EntityLike {
}
}
/// Return an error unless this is a struct with named fields.
///
/// # Parameters
///
/// * `kind`, the attribute name (e.g., `input` or `interned`)
pub(crate) fn require_named_fields(&self, kind: &str) -> syn::Result<()> {
if !self.has_named_fields() {
return Err(syn::Error::new(
self.id_ident().span(),
"`#[salsa::{kind}]` can only be applied to a struct with named fields",
));
}
Ok(())
}
/// Disallow `#[id]` attributes on the fields of this struct.
///
/// If an `#[id]` field is found, return an error.
///
/// # Parameters
///
/// * `kind`, the attribute name (e.g., `input` or `interned`)
pub(crate) fn disallow_id_fields(&self, kind: &str) -> syn::Result<()> {
for ef in self.all_entity_fields() {
if ef.has_id_attr {
return Err(syn::Error::new(
ef.name().span(),
"`#[id]` cannot be used with `#[salsa::{kind}]`",
));
}
}
Ok(())
}
}
pub(crate) const FIELD_OPTION_ATTRIBUTES: &[(&str, fn(&syn::Attribute, &mut EntityField))] = &[

View file

@ -41,20 +41,7 @@ impl EntityLike {
}
fn validate_interned(&self) -> syn::Result<()> {
// Disallow `#[value]` attributes on interned things.
//
// They don't really make sense -- we intern all the fields of something
// to create its id. If multiple queries were to intern the same thing with
// distinct values for the value field, what would happen?
for ef in self.all_entity_fields() {
if ef.has_id_attr {
return Err(syn::Error::new(
ef.name().span(),
"`#[id]` not required in interned structs",
));
}
}
self.disallow_id_fields("interned")?;
Ok(())
}