tamer: asg::graph::Asg{Object=>Rel}Mut: Trait-level target type

This allows for a declarative matching on edge targets using the trait
system, rather than having to convert the type to a runtime value to match
on (which doesn't make a whole lot of sense).

See a commit to follow shortly (with Tpl) for an example use case.

DEV-13163
main
Mike Gerwitz 2023-07-25 11:15:41 -04:00
parent 2ecc143e02
commit 4168c579fd
10 changed files with 18 additions and 17 deletions

View File

@ -393,7 +393,7 @@ fn diagnostic_node_missing_desc<O: ObjectKind>(
]
}
/// Mutation of an [`Object`] or its edges on the [`Asg`].
/// Mutation of an [`Object`]'s relationships (edges) on the [`Asg`].
///
/// This trait is intended to delegate certain responsibilities to
/// [`ObjectKind`]s so that they may enforce their own invariants with
@ -403,7 +403,7 @@ fn diagnostic_node_missing_desc<O: ObjectKind>(
/// trait,
/// but the current module structure together with Rust's visibility
/// with sibling modules doesn't seem to make that possible.
pub trait AsgObjectMut: ObjectKind {
pub trait AsgRelMut<OB: ObjectRelatable>: ObjectKind {
/// Allow an object to handle or reject the creation of an edge from it
/// to another object.
///
@ -434,7 +434,7 @@ pub trait AsgObjectMut: ObjectKind {
/// Unlike the type of [`Asg::add_edge`],
/// the source [`ObjectIndex`] has been narrowed to the appropriate
/// type for you.
fn pre_add_edge<OB: ObjectKind + ObjectRelatable>(
fn pre_add_edge(
asg: &mut Asg,
_from_oi: ObjectIndex<Self>,
_to_oi: ObjectIndex<OB>,

View File

@ -114,8 +114,8 @@
//! follow an edge to an unexpected [`ObjectKind`].
//!
//! In addition to these static guarantees,
//! [`AsgObjectMut`](super::AsgObjectMut) is utilized by [`Asg`] to
//! consult an object before an edge is added _from_ it,
//! [`AsgRelMut`](super::AsgRelMut) is utilized by [`Asg`] to consult an
//! object before an edge is added _from_ it,
//! allowing objects to assert ownership over their edges and cache
//! information about them as the graph is being built.
@ -162,7 +162,7 @@ pub use tpl::Tpl;
/// Often-needed exports for [`ObjectKind`]s.
pub mod prelude {
pub use super::{
super::{super::error::AsgError, Asg, AsgObjectMut},
super::{super::error::AsgError, Asg, AsgRelMut},
Object, ObjectIndex, ObjectIndexRelTo, ObjectKind, ObjectRel,
ObjectRelFrom, ObjectRelTo, ObjectRelTy, ObjectRelatable,
ObjectTreeRelTo,

View File

@ -92,4 +92,4 @@ object_rel! {
}
}
impl AsgObjectMut for Doc {}
impl<OB: ObjectRelatable> AsgRelMut<OB> for Doc {}

View File

@ -269,4 +269,4 @@ impl ObjectIndex<Expr> {
}
}
impl AsgObjectMut for Expr {}
impl<OB: ObjectRelatable> AsgRelMut<OB> for Expr {}

View File

@ -1406,7 +1406,7 @@ impl ObjectIndex<Ident> {
}
}
impl AsgObjectMut for Ident {}
impl<OB: ObjectRelatable> AsgRelMut<OB> for Ident {}
#[cfg(test)]
mod test;

View File

@ -307,4 +307,4 @@ impl ObjectIndex<Meta> {
}
}
impl AsgObjectMut for Meta {}
impl<OB: ObjectRelatable> AsgRelMut<OB> for Meta {}

View File

@ -148,4 +148,4 @@ impl ObjectIndex<Pkg> {
}
}
impl AsgObjectMut for Pkg {}
impl<OB: ObjectRelatable> AsgRelMut<OB> for Pkg {}

View File

@ -27,7 +27,7 @@ use super::{
};
use crate::{
asg::{
graph::{object::Tpl, AsgObjectMut},
graph::{object::Tpl, AsgRelMut},
Asg, AsgError,
},
f::Functor,
@ -504,7 +504,8 @@ impl<T: Display> Display for DynObjectRel<T> {
/// statically analyzed by the type system to ensure that they only
/// construct graphs that adhere to this schema.
pub trait ObjectRelTo<OB: ObjectKind + ObjectRelatable> =
ObjectRelatable where <Self as ObjectRelatable>::Rel: From<ObjectIndex<OB>>;
ObjectRelatable + AsgRelMut<OB>
where <Self as ObjectRelatable>::Rel: From<ObjectIndex<OB>>;
/// Reverse of [`ObjectRelTo`].
///
@ -532,7 +533,7 @@ pub trait ObjectTreeRelTo<OB: ObjectKind + ObjectRelatable>:
/// This is used to derive [`ObjectRelTo``],
/// which can be used as a trait bound to assert a valid relationship
/// between two [`Object`]s.
pub trait ObjectRelatable: ObjectKind + AsgObjectMut {
pub trait ObjectRelatable: ObjectKind {
/// Sum type representing a subset of [`Object`] variants that are valid
/// targets for edges from [`Self`].
///
@ -840,7 +841,7 @@ pub trait ObjectIndexRelTo<OB: ObjectRelatable>: Sized + Clone + Copy {
/// without sacrificing edge ownership.
///
/// For more information,
/// see [`AsgObjectMut::pre_add_edge`].
/// see [`AsgRelMut::pre_add_edge`].
///
/// _This should only be called by [`Asg`]_;
/// `commit` is expected to be a continuation that adds the edge to

View File

@ -71,4 +71,4 @@ impl ObjectIndex<Root> {
}
}
impl AsgObjectMut for Root {}
impl<OB: ObjectRelatable> AsgRelMut<OB> for Root {}

View File

@ -132,4 +132,4 @@ impl ObjectIndex<Tpl> {
}
}
impl AsgObjectMut for Tpl {}
impl<OB: ObjectRelatable> AsgRelMut<OB> for Tpl {}