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

View File

@ -114,8 +114,8 @@
//! follow an edge to an unexpected [`ObjectKind`]. //! follow an edge to an unexpected [`ObjectKind`].
//! //!
//! In addition to these static guarantees, //! In addition to these static guarantees,
//! [`AsgObjectMut`](super::AsgObjectMut) is utilized by [`Asg`] to //! [`AsgRelMut`](super::AsgRelMut) is utilized by [`Asg`] to consult an
//! consult an object before an edge is added _from_ it, //! object before an edge is added _from_ it,
//! allowing objects to assert ownership over their edges and cache //! allowing objects to assert ownership over their edges and cache
//! information about them as the graph is being built. //! information about them as the graph is being built.
@ -162,7 +162,7 @@ pub use tpl::Tpl;
/// Often-needed exports for [`ObjectKind`]s. /// Often-needed exports for [`ObjectKind`]s.
pub mod prelude { pub mod prelude {
pub use super::{ pub use super::{
super::{super::error::AsgError, Asg, AsgObjectMut}, super::{super::error::AsgError, Asg, AsgRelMut},
Object, ObjectIndex, ObjectIndexRelTo, ObjectKind, ObjectRel, Object, ObjectIndex, ObjectIndexRelTo, ObjectKind, ObjectRel,
ObjectRelFrom, ObjectRelTo, ObjectRelTy, ObjectRelatable, ObjectRelFrom, ObjectRelTo, ObjectRelTy, ObjectRelatable,
ObjectTreeRelTo, 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)] #[cfg(test)]
mod 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::{ use crate::{
asg::{ asg::{
graph::{object::Tpl, AsgObjectMut}, graph::{object::Tpl, AsgRelMut},
Asg, AsgError, Asg, AsgError,
}, },
f::Functor, f::Functor,
@ -504,7 +504,8 @@ impl<T: Display> Display for DynObjectRel<T> {
/// statically analyzed by the type system to ensure that they only /// statically analyzed by the type system to ensure that they only
/// construct graphs that adhere to this schema. /// construct graphs that adhere to this schema.
pub trait ObjectRelTo<OB: ObjectKind + ObjectRelatable> = 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`]. /// Reverse of [`ObjectRelTo`].
/// ///
@ -532,7 +533,7 @@ pub trait ObjectTreeRelTo<OB: ObjectKind + ObjectRelatable>:
/// This is used to derive [`ObjectRelTo``], /// This is used to derive [`ObjectRelTo``],
/// which can be used as a trait bound to assert a valid relationship /// which can be used as a trait bound to assert a valid relationship
/// between two [`Object`]s. /// between two [`Object`]s.
pub trait ObjectRelatable: ObjectKind + AsgObjectMut { pub trait ObjectRelatable: ObjectKind {
/// Sum type representing a subset of [`Object`] variants that are valid /// Sum type representing a subset of [`Object`] variants that are valid
/// targets for edges from [`Self`]. /// targets for edges from [`Self`].
/// ///
@ -840,7 +841,7 @@ pub trait ObjectIndexRelTo<OB: ObjectRelatable>: Sized + Clone + Copy {
/// without sacrificing edge ownership. /// without sacrificing edge ownership.
/// ///
/// For more information, /// For more information,
/// see [`AsgObjectMut::pre_add_edge`]. /// see [`AsgRelMut::pre_add_edge`].
/// ///
/// _This should only be called by [`Asg`]_; /// _This should only be called by [`Asg`]_;
/// `commit` is expected to be a continuation that adds the edge to /// `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 {}