use darling::util::{Flag, SpannedValue};
use darling::{Error, FromField, error::Accumulator};
use syn::{Ident, Path, Type};
use crate::types::{NoneOrder, SortOrder};
#[derive(Debug, Clone, FromField)]
#[darling(attributes(ord))]
pub struct OrdField {
pub ident: Option<Ident>,
#[allow(dead_code)]
pub ty: Type,
#[darling(default)]
pub skip: Flag,
pub order: Option<SortOrder>,
pub priority: Option<SpannedValue<i32>>,
pub key: Option<SpannedValue<Path>>,
pub none_order: Option<NoneOrder>,
}
impl OrdField {
pub fn effective_order(&self) -> SortOrder {
self.order.unwrap_or_default()
}
pub fn effective_priority(&self) -> i32 {
self.priority.as_ref().map_or(i32::MAX, |p| **p)
}
pub fn check_skipped(&self, errors: &mut Accumulator) {
if !self.skip.is_present() {
return;
}
let conflicts = [
("order", self.order.is_some()),
("priority", self.priority.is_some()),
("key", self.key.is_some()),
("none_order", self.none_order.is_some()),
];
for (name, present) in conflicts {
if present {
errors.push(
Error::custom(format!("cannot use `{name}` on skipped fields"))
.with_span(&self.skip.span()),
);
}
}
}
}