use xuanji::{RuleKey, Severity};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TraitImplBoundary {
pub(crate) crate_package: String,
pub(crate) trait_path: String,
pub(crate) allowed_locations: Vec<String>,
pub(crate) reason: String,
pub(crate) anchor: Option<String>,
pub(crate) severity: Severity,
}
impl TraitImplBoundary {
pub fn rule_key(&self) -> RuleKey {
self.rule_key_for_anchor(&super::canonical_path(&self.trait_path))
}
pub(crate) fn rule_key_for_anchor(&self, trait_anchor: &str) -> RuleKey {
RuleKey::of(
"tianheng.rule/hunyi/trait-impl-locality",
[
(
"allowed_locations",
super::canonical_path_set(&self.allowed_locations),
),
("trait", trait_anchor.to_string()),
],
)
}
pub fn in_crate(package: &str) -> TraitImplCrateDraft {
TraitImplCrateDraft {
crate_package: package.to_string(),
}
}
pub fn trait_(&self) -> &str {
&self.trait_path
}
pub fn allowed_locations(&self) -> &[String] {
&self.allowed_locations
}
pub fn reason(&self) -> &str {
&self.reason
}
}
crate::dsl::boundary_common!(TraitImplBoundary, TraitImplBoundaryDraft);
#[doc(hidden)]
pub struct TraitImplCrateDraft {
crate_package: String,
}
impl TraitImplCrateDraft {
pub fn trait_(self, trait_path: &str) -> TraitImplTraitDraft {
TraitImplTraitDraft {
crate_package: self.crate_package,
trait_path: trait_path.to_string(),
}
}
}
#[doc(hidden)]
pub struct TraitImplTraitDraft {
crate_package: String,
trait_path: String,
}
impl TraitImplTraitDraft {
pub fn only_implemented_in(self, location: &str) -> TraitImplBoundaryDraft {
TraitImplBoundaryDraft {
crate_package: self.crate_package,
trait_path: self.trait_path,
allowed_locations: vec![location.to_string()],
severity: Severity::Enforce,
}
}
}
#[doc(hidden)]
pub struct TraitImplBoundaryDraft {
crate_package: String,
trait_path: String,
allowed_locations: Vec<String>,
severity: Severity,
}
impl TraitImplBoundaryDraft {
pub fn and_in(mut self, location: &str) -> Self {
self.allowed_locations.push(location.to_string());
self
}
pub fn because(self, reason: &str) -> TraitImplBoundary {
TraitImplBoundary {
crate_package: self.crate_package,
trait_path: self.trait_path,
allowed_locations: self.allowed_locations,
reason: reason.to_string(),
anchor: None,
severity: self.severity,
}
}
}