persian_rug/
lib.rs

1//! This crate provides a framework for managing arbitrary mutable
2//! graphs of objects that link to one another. This is a pattern
3//! which is difficult to replicate in Rust, because of the ownership
4//! model, but is common in the wider software ecosystem.
5//!
6//! # Overview and motivation
7//!
8//! In the case where you have truly arbitrary graphs, most of an object's
9//! dependencies cannot be usefully represented as being owned by that object.
10//! For example, consider two types, `Foo` and `Bar`:
11//!
12//! ```rust
13//! struct Foo {
14//!     bars: Vec<Bar>
15//! }
16//!
17//! struct Bar {
18//!     my_special_foo: Option<Foo>
19//! }
20//! ```
21//!
22//! If no one `Foo` is the sole owner of a `Bar` (each `Foo` holds a
23//! subset of available `Bar`s), and no one `Bar` is the sole owner of
24//! any given `Foo` (the same `Foo` could be special for multiple
25//! `Bar`s), then we end up with multiple copies of every object in
26//! this representation, and maintaining consistency is likely to be
27//! difficult.
28//!
29//! We might next try to use reference counting smart pointers for the
30//! links between objects, but neither [`Rc`](std::rc::Rc) nor
31//! [`Arc`](std::sync::Arc) gives us mutability on its own. If we then
32//! consider using [`Mutex`](std::sync::Mutex) to provide mutability, we
33//! end up with something like this:
34//!
35//! ```rust
36//! use std::sync::{Arc, Mutex};
37//!
38//! struct Foo {
39//!     bars: Vec<Arc<Mutex<Bar>>>
40//! }
41//!
42//! struct Bar {
43//!     my_special_foo: Option<Arc<Mutex<Foo>>>
44//! }
45//! ```
46//!
47//! in which each object is individually lockable to permit
48//! mutation. But there is no meaningful lock order here, and deadlock
49//! is all but assured.
50//!
51//! The approach taken in this crate is to store everything inside one
52//! container (a [`Context`]) which gives a single location for locking.
53//! Only the [`Context`] has ownership of data, everything else is
54//! granted a [`Proxy`] which can be resolved using the [`Context`] into a
55//! reference to the real object. We use attribute macros to
56//! remove most of the boilerplate: [`contextual`] matches a type to
57//! its owner, and [`persian_rug`] builds a suitable owner.
58//!
59//! That means the example using this crate looks like this:
60//!
61//! ```rust
62//! use persian_rug::{contextual, persian_rug, Proxy};
63//!
64//! #[contextual(MyRug)]
65//! struct Foo {
66//!   bars: Vec<Proxy<Bar>>
67//! }
68//!
69//! #[contextual(MyRug)]
70//! struct Bar {
71//!   my_special_foo: Option<Proxy<Foo>>
72//! }
73//!
74//! #[persian_rug]
75//! struct MyRug(#[table] Foo, #[table] Bar);
76//! ```
77//!
78//! We will need to have an instance of `MyRug` available whenever we
79//! want to read the contents of a `Foo` or a `Bar`. If we have a
80//! mutable reference to the context, we can change any `Foo` or `Bar`
81//! we wish.
82//!
83//! # The Persian Rug
84//!
85//! A [`Context`] provides the ability to insert, retrieve and iterate
86//! over items by type. It can only support one collection of items
87//! per type.
88//!
89//! > Please note:
90//! > **this crate does not support deletion of objects** at present.
91//!
92//! ```rust
93//! use persian_rug::{contextual, persian_rug, Context, Proxy, Table};
94//!
95//! #[contextual(C)]
96//! struct Foo<C: Context> {
97//!   _marker: core::marker::PhantomData<C>,
98//!   pub a: i32,
99//!   pub friend: Option<Proxy<Foo<C>>>
100//! }
101//!
102//! impl<C: Context> Foo<C> {
103//!   pub fn new(a: i32, friend: Option<Proxy<Foo<C>>>) -> Self {
104//!     Self { _marker: Default::default(), a, friend }
105//!   }
106//! }
107//!
108//! #[persian_rug]
109//! struct Rug(#[table] Foo<Rug>);
110//!
111//! let mut r = Rug(Table::new());
112//! let p1 = r.add( Foo::new(1, None) );
113//! let p2 = r.add( Foo::new(2, Some(p1)) );
114//! let p3 = r.add( Foo::new(3, Some(p2)) );
115//! r.get_mut(&p1).friend = Some(p3);
116//!
117//! ```
118//!
119//! Context read access is provided to implementations of [`Accessor`]
120//! whose context matches. Shared references to the context are
121//! accessors, as are [`Arc`](std::sync::Arc)s,
122//! [`MutexGuard`](std::sync::MutexGuard)s and
123//! [`RwLockReadGuard`](std::sync::RwLockReadGuard)s.
124//!
125//! Write access is provided to implementations of [`Mutator`] whose
126//! context matches.  Exclusive references to the context are
127//! mutators, as are [`MutexGuard`](std::sync::MutexGuard)s and
128//! [`RwLockWriteGuard`](std::sync::RwLockWriteGuard)s. If you enable
129//! the `clone-replace` feature, you can also use
130//! [`MutateGuard`](clone_replace::MutateGuard)s for this.
131//!
132//! To prevent accidental misuse, each participating type must declare
133//! its context by implementing [`Contextual`], and can only belong to
134//! one context. This apparent restriction is easily lifted by making
135//! the context a generic parameter of the participating type. The
136//! [`constraints`] attribute can help with the boilerplate needed to
137//! use generic parameters in this way.
138
139use std::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
140use std::collections::BTreeMap;
141use std::hash::{Hash, Hasher};
142
143/// A holder for [`Contextual`] types.
144///
145/// This is the "rug" in persian-rug (and in the examples, the context
146/// is often called `Rug`). The implementor is the sole owner for the
147/// [`Contextual`] objects it contains, and is responsible for resolving
148/// [`Proxy`] objects into references to its owned copies.
149///
150/// You will not generally implement this trait directly. The
151/// [`persian_rug`] attribute macro sets up the necessary
152/// implementations for a usable [`Context`], converting each marked
153/// field into a [`Table`], and providing an implementation of
154/// [`Owner`] for each included type.
155///
156/// A context should only have one field of a given type. Its purpose
157/// is to conveniently resolve [`Proxy`] objects and hold data; actual
158/// data organisation ought to be done in a different object, by
159/// holding whatever objects are required, in whatever organisation is
160/// required, as proxies.
161pub trait Context {
162    /// Insert the given value, returning a [`Proxy`] for it.
163    fn add<T>(&mut self, value: T) -> Proxy<T>
164    where
165        Self: Owner<T>,
166        T: Contextual<Context = Self>;
167
168    /// Retrieve a reference to a value from a [`Proxy`].
169    fn get<T>(&self, what: &Proxy<T>) -> &T
170    where
171        Self: Owner<T>,
172        T: Contextual<Context = Self>;
173
174    /// Retrieve a mutable reference to a value from a [`Proxy`].
175    fn get_mut<T>(&mut self, what: &Proxy<T>) -> &mut T
176    where
177        Self: Owner<T>,
178        T: Contextual<Context = Self>;
179
180    /// Iterate over the values currently stored.
181    fn get_iter<T>(&self) -> TableIterator<'_, T>
182    where
183        Self: Owner<T>,
184        T: Contextual<Context = Self>;
185
186    /// Mutably iterate over the values currently stored.
187    fn get_iter_mut<T>(&mut self) -> TableMutIterator<'_, T>
188    where
189        Self: Owner<T>,
190        T: Contextual<Context = Self>;
191
192    /// Iterate over (owned) proxies for the values currently stored.
193    fn get_proxy_iter<T>(&self) -> TableProxyIterator<'_, T>
194    where
195        Self: Owner<T>,
196        T: Contextual<Context = Self>;
197}
198
199/// A convenient way to handle [`Context`] read access.
200///
201/// Rather than plumbing references to a context throughout your code,
202/// especially when you are implementing derive macros that rely on
203/// this crate, it can be more convenient to use this abstraction of
204/// read-only access to a context.
205///
206/// In most hand-written code, it is simplest to use a shared
207/// reference to a context as an Accessor.
208pub trait Accessor: Clone {
209    type Context: Context;
210
211    fn get<T>(&self, what: &Proxy<T>) -> &T
212    where
213        Self::Context: Owner<T>,
214        T: Contextual<Context = Self::Context>;
215
216    fn get_iter<T>(&self) -> TableIterator<'_, T>
217    where
218        Self::Context: Owner<T>,
219        T: Contextual<Context = Self::Context>;
220
221    fn get_proxy_iter<T>(&self) -> TableProxyIterator<'_, T>
222    where
223        Self::Context: Owner<T>,
224        T: Contextual<Context = Self::Context>;
225}
226
227impl<'a, C> Accessor for &'a C
228where
229    C: Context,
230{
231    type Context = C;
232
233    fn get<T>(&self, what: &Proxy<T>) -> &T
234    where
235        Self::Context: Owner<T>,
236        T: Contextual<Context = Self::Context>,
237    {
238        <C as Context>::get(self, what)
239    }
240
241    fn get_iter<T>(&self) -> TableIterator<'_, T>
242    where
243        Self::Context: Owner<T>,
244        T: Contextual<Context = Self::Context>,
245    {
246        <C as Context>::get_iter(self)
247    }
248
249    fn get_proxy_iter<T>(&self) -> TableProxyIterator<'_, T>
250    where
251        Self::Context: Owner<T>,
252        T: Contextual<Context = Self::Context>,
253    {
254        <C as Context>::get_proxy_iter(self)
255    }
256}
257
258impl<C> Accessor for std::sync::Arc<C>
259where
260    C: Context,
261{
262    type Context = C;
263    fn get<T>(&self, what: &Proxy<T>) -> &T
264    where
265        Self::Context: Owner<T>,
266        T: Contextual<Context = Self::Context>,
267    {
268        <C as Context>::get(self, what)
269    }
270
271    fn get_iter<T>(&self) -> TableIterator<'_, T>
272    where
273        Self::Context: Owner<T>,
274        T: Contextual<Context = Self::Context>,
275    {
276        <C as Context>::get_iter(self)
277    }
278
279    fn get_proxy_iter<T>(&self) -> TableProxyIterator<'_, T>
280    where
281        Self::Context: Owner<T>,
282        T: Contextual<Context = Self::Context>,
283    {
284        <C as Context>::get_proxy_iter(self)
285    }
286}
287
288/// A convenient way to handle [`Context`] write access.
289///
290/// Rather than plumbing references to a context throughout your code,
291/// especially when you are implementing derive macros that rely on
292/// this crate, it can be more convenient to use this abstraction of
293/// read-write access to a context.
294///
295/// In most hand-written code, it is simplest to use an exclusive
296/// reference to a context as a Mutator.
297pub trait Mutator {
298    type Context: Context;
299
300    fn add<T>(&mut self, proxy: T) -> Proxy<T>
301    where
302        Self::Context: Owner<T>,
303        T: Contextual<Context = Self::Context>;
304
305    fn get<T>(&self, what: &Proxy<T>) -> &T
306    where
307        Self::Context: Owner<T>,
308        T: Contextual<Context = Self::Context>;
309
310    fn get_mut<T>(&mut self, what: &Proxy<T>) -> &mut T
311    where
312        Self::Context: Owner<T>,
313        T: Contextual<Context = Self::Context>;
314
315    fn get_iter<T>(&self) -> TableIterator<'_, T>
316    where
317        Self::Context: Owner<T>,
318        T: Contextual<Context = Self::Context>;
319
320    fn get_iter_mut<T>(&mut self) -> TableMutIterator<'_, T>
321    where
322        Self::Context: Owner<T>,
323        T: Contextual<Context = Self::Context>;
324
325    fn get_proxy_iter<T>(&self) -> TableProxyIterator<'_, T>
326    where
327        Self::Context: Owner<T>,
328        T: Contextual<Context = Self::Context>;
329}
330
331impl<'a, C> Mutator for &'a mut C
332where
333    C: Context,
334{
335    type Context = C;
336
337    fn add<T>(&mut self, value: T) -> Proxy<T>
338    where
339        Self::Context: Owner<T>,
340        T: Contextual<Context = Self::Context>,
341    {
342        <C as Context>::add(self, value)
343    }
344
345    fn get<T>(&self, what: &Proxy<T>) -> &T
346    where
347        Self::Context: Owner<T>,
348        T: Contextual<Context = Self::Context>,
349    {
350        <C as Context>::get(self, what)
351    }
352
353    fn get_mut<T>(&mut self, what: &Proxy<T>) -> &mut T
354    where
355        Self::Context: Owner<T>,
356        T: Contextual<Context = Self::Context>,
357    {
358        <C as Context>::get_mut(self, what)
359    }
360
361    fn get_iter<T>(&self) -> TableIterator<'_, T>
362    where
363        Self::Context: Owner<T>,
364        T: Contextual<Context = Self::Context>,
365    {
366        <C as Context>::get_iter(self)
367    }
368
369    fn get_iter_mut<T>(&mut self) -> TableMutIterator<'_, T>
370    where
371        Self::Context: Owner<T>,
372        T: Contextual<Context = Self::Context>,
373    {
374        <C as Context>::get_iter_mut(self)
375    }
376
377    fn get_proxy_iter<T>(&self) -> TableProxyIterator<'_, T>
378    where
379        Self::Context: Owner<T>,
380        T: Contextual<Context = Self::Context>,
381    {
382        <C as Context>::get_proxy_iter(self)
383    }
384}
385
386impl<'a, C> Mutator for std::sync::MutexGuard<'a, C>
387where
388    C: Context,
389{
390    type Context = C;
391
392    fn add<T>(&mut self, value: T) -> Proxy<T>
393    where
394        Self::Context: Owner<T>,
395        T: Contextual<Context = Self::Context>,
396    {
397        <C as Context>::add(self, value)
398    }
399
400    fn get<T>(&self, what: &Proxy<T>) -> &T
401    where
402        Self::Context: Owner<T>,
403        T: Contextual<Context = Self::Context>,
404    {
405        <C as Context>::get(self, what)
406    }
407
408    fn get_mut<T>(&mut self, what: &Proxy<T>) -> &mut T
409    where
410        Self::Context: Owner<T>,
411        T: Contextual<Context = Self::Context>,
412    {
413        <C as Context>::get_mut(self, what)
414    }
415
416    fn get_iter<T>(&self) -> TableIterator<'_, T>
417    where
418        Self::Context: Owner<T>,
419        T: Contextual<Context = Self::Context>,
420    {
421        <C as Context>::get_iter(self)
422    }
423
424    fn get_iter_mut<T>(&mut self) -> TableMutIterator<'_, T>
425    where
426        Self::Context: Owner<T>,
427        T: Contextual<Context = Self::Context>,
428    {
429        <C as Context>::get_iter_mut(self)
430    }
431
432    fn get_proxy_iter<T>(&self) -> TableProxyIterator<'_, T>
433    where
434        Self::Context: Owner<T>,
435        T: Contextual<Context = Self::Context>,
436    {
437        <C as Context>::get_proxy_iter(self)
438    }
439}
440
441impl<'a, C> Mutator for std::sync::RwLockWriteGuard<'a, C>
442where
443    C: Context,
444{
445    type Context = C;
446
447    fn add<T>(&mut self, value: T) -> Proxy<T>
448    where
449        Self::Context: Owner<T>,
450        T: Contextual<Context = Self::Context>,
451    {
452        <C as Context>::add(self, value)
453    }
454
455    fn get<T>(&self, what: &Proxy<T>) -> &T
456    where
457        Self::Context: Owner<T>,
458        T: Contextual<Context = Self::Context>,
459    {
460        <C as Context>::get(self, what)
461    }
462
463    fn get_mut<T>(&mut self, what: &Proxy<T>) -> &mut T
464    where
465        Self::Context: Owner<T>,
466        T: Contextual<Context = Self::Context>,
467    {
468        <C as Context>::get_mut(self, what)
469    }
470
471    fn get_iter<T>(&self) -> TableIterator<'_, T>
472    where
473        Self::Context: Owner<T>,
474        T: Contextual<Context = Self::Context>,
475    {
476        <C as Context>::get_iter(self)
477    }
478
479    fn get_iter_mut<T>(&mut self) -> TableMutIterator<'_, T>
480    where
481        Self::Context: Owner<T>,
482        T: Contextual<Context = Self::Context>,
483    {
484        <C as Context>::get_iter_mut(self)
485    }
486
487    fn get_proxy_iter<T>(&self) -> TableProxyIterator<'_, T>
488    where
489        Self::Context: Owner<T>,
490        T: Contextual<Context = Self::Context>,
491    {
492        <C as Context>::get_proxy_iter(self)
493    }
494}
495
496#[cfg(feature = "clone-replace")]
497impl<C> Mutator for clone_replace::MutateGuard<C>
498where
499    C: Context,
500{
501    type Context = C;
502
503    fn add<T>(&mut self, value: T) -> Proxy<T>
504    where
505        Self::Context: Owner<T>,
506        T: Contextual<Context = Self::Context>,
507    {
508        <C as Context>::add(self, value)
509    }
510
511    fn get<T>(&self, what: &Proxy<T>) -> &T
512    where
513        Self::Context: Owner<T>,
514        T: Contextual<Context = Self::Context>,
515    {
516        <C as Context>::get(self, what)
517    }
518
519    fn get_mut<T>(&mut self, what: &Proxy<T>) -> &mut T
520    where
521        Self::Context: Owner<T>,
522        T: Contextual<Context = Self::Context>,
523    {
524        <C as Context>::get_mut(self, what)
525    }
526
527    fn get_iter<T>(&self) -> TableIterator<'_, T>
528    where
529        Self::Context: Owner<T>,
530        T: Contextual<Context = Self::Context>,
531    {
532        <C as Context>::get_iter(self)
533    }
534
535    fn get_iter_mut<T>(&mut self) -> TableMutIterator<'_, T>
536    where
537        Self::Context: Owner<T>,
538        T: Contextual<Context = Self::Context>,
539    {
540        <C as Context>::get_iter_mut(self)
541    }
542
543    fn get_proxy_iter<T>(&self) -> TableProxyIterator<'_, T>
544    where
545        Self::Context: Owner<T>,
546        T: Contextual<Context = Self::Context>,
547    {
548        <C as Context>::get_proxy_iter(self)
549    }
550}
551
552/// A type that owns (is the exclusive holder of) a [`Contextual`] type.
553///
554/// Implementations of this trait are normally provided for you by the
555/// [`persian_rug`] attribute macro. You should rarely, if ever, need to
556/// implement it yourself.
557///
558/// Each [`Contextual`] type has a single [`Context`] that owns it. Only
559/// that context may implement this trait for the type, which provides
560/// the standard API for [`Context`] objects, specialised to a single
561/// type. The polymorphic interface for contexts calls through to the
562/// functions defined in this trait, and you should never need to
563/// call them directly; it is preferable to use the [`Context`] interface.
564///
565/// The main place in which [`Owner`] shows up in code written using
566/// this crate is when specifying the constraints on what contexts are
567/// permitted to call a given generic function. In general, those uses
568/// of [`Owner`] can also be generated for you, using the [`constraints`]
569/// attribute macro, but there are cases where you may need to refer
570/// to it yourself: essentially whenever you need to assert that you
571/// will be able to interact with a type `T` or a proxy for it, via
572/// some context, then you can assert that the context implements
573/// `Owner<T>`.
574pub trait Owner<T>: Context
575where
576    T: Contextual<Context = Self>,
577{
578    /// Insert the given value, obtaining a [`Proxy`] for it.
579    fn add(&mut self, value: T) -> Proxy<T>;
580    /// Get a shared reference to a value from a [`Proxy`] for it.
581    fn get(&self, proxy: &Proxy<T>) -> &T;
582    /// Get an exclusive reference to a value from a [`Proxy`] for it.    
583    fn get_mut(&mut self, proxy: &Proxy<T>) -> &mut T;
584    /// Iterate over shared references to the stored values.
585    fn get_iter(&self) -> TableIterator<'_, T>;
586    /// Iterate over exclusive references to the stored values.
587    fn get_iter_mut(&mut self) -> TableMutIterator<'_, T>;
588    /// Iterate over shared references to [`Proxy`] objects for the
589    /// stored values.
590    fn get_proxy_iter(&self) -> TableProxyIterator<'_, T>;
591}
592
593/// Something that is associated to a context
594///
595/// An implementor of Contextual expects to be stored in a [`Table`]
596/// in some other [`Context`] type. Generally, you want to do this if
597/// there is some arbitrary object graph in which this participates,
598/// where you want to link between objects with [`Proxy`] handles
599/// provided by a [`Context`].  Even if your class itself contains no
600/// links, and so could be adequately modeled by holding
601/// [`Rc`](std::rc::Rc) or [`Arc`](std::sync::Arc) references to it,
602/// you might opt to include it within a context for consistency, if
603/// it's logically part of a larger whole which is mostly modeled
604/// using this crate.
605///
606/// You will not generally implement this trait directly yourself,
607/// instead you can use the attribute macro [`contextual`] to create
608/// the necessary impl for you.
609///
610/// For types that don't necessarily always belong to the same [`Context`],
611/// which is to say any types that could be re-used in a different scenario,
612/// the recommended pattern is to make the context a generic parameter. For example:
613///
614/// ```rust
615/// use persian_rug::{contextual, Context, Contextual};
616///
617/// #[contextual(C)]
618/// struct Foo<C: Context> {
619///   _marker: core::marker::PhantomData<C>
620/// }
621/// ```
622///
623/// The [`PhantomData`](core::marker::PhantomData) is only needed if your type
624/// does not contain anything else to establish the context from. If you
625/// contain another contextual type you can use that instead, for example:
626/// ```rust
627/// use persian_rug::{contextual, Context, Contextual, Proxy};
628///
629/// #[contextual(<T as Contextual>::Context)]
630/// struct Bar<T: Contextual> {
631///   my_proxy: Proxy<T>
632/// }
633/// ```
634///
635/// If you have collections of objects for which not all are required in every use case,
636/// you might end up with a pattern like this:
637///
638/// ```rust
639/// use persian_rug::{contextual, Context, Contextual, Proxy};
640///
641/// #[contextual(C)]
642/// struct Foo<C: Context> {
643///   _marker: core::marker::PhantomData<C>
644/// }
645///
646/// #[contextual(C)]
647/// struct Bar<C: Context> {
648///   foo: Proxy<C>
649/// }
650///
651/// ```
652///
653/// where it's possible to create a working [`Context`] that contains
654/// only `Foo`s, or one that contains both `Foo`s and `Bar`s.
655///
656/// Having multiple different contexts for a single type is not
657/// supported, and similarly holding [`Proxy`] objects for two
658/// different contexts is likely to result in some difficulty. In
659/// general, it is better to design your types to be usable in
660/// different contexts if needed, as discussed above, but always
661/// include everything needed in a given scenario in the same context.
662pub trait Contextual {
663    /// The [`Context`] type which owns values of this type.
664    type Context: Context;
665}
666
667/// A handle to an item stored in some context.
668///
669/// A proxy is a link between objects, like [`Arc`](std::sync::Arc) or
670/// [`Rc`](std::rc::Rc). It allows multiple objects to reference a
671/// single other object, without any one of them being declared the
672/// owner. Unlike reference counted smart pointers, you need to
673/// provide its [`Context`] to traverse the link represented by a [`Proxy`].
674///
675/// When writing code that makes use of proxies, things are made more
676/// complicated by the need to ensure the right kind of access for the
677/// context is available (i.e. every function is likely to receive
678/// either a [`Mutator`] or an [`Accessor`] parameter, depending on
679/// whether mutable access is needed. However, things are made simpler
680/// in terms of establishing that access is safe, since there is only
681/// one object to which you need a mutable reference: the context
682/// object.
683///
684/// The following example traverses an arbitrary graph of `Foo`s
685/// (checking for cycles by never revisiting any node). There are of
686/// course other ways of doing this (both in Rust, and using this
687/// crate), but holding and working with such graphs is generally
688/// considered challenging in Rust. As the example shows, it can be
689/// relatively convenient to do so using this crate:
690/// ```rust
691/// use persian_rug::{contextual, persian_rug, Accessor, Context, Contextual, Proxy};
692/// use std::collections::BTreeSet;
693///
694/// #[contextual(Rug)]
695/// struct Foo {
696///    id: String,
697///    links: Vec<Proxy<Foo>>
698/// }
699///
700/// impl Foo {
701///   pub fn print_graph<A: Accessor<Context=Rug>>(&self, access: A) {
702///     let mut b = BTreeSet::new();
703///     let mut work = Vec::new();
704///     work.push(self);
705///     while let Some(item) = work.pop() {
706///       println!("{}", item.id);
707///       b.insert(item.id.clone());
708///       for link in &item.links {
709///         let link = access.get(link);
710///         if !b.contains(&link.id) {
711///           work.push(link);
712///         }
713///       }
714///     }
715///   }
716/// }
717///
718/// #[persian_rug]
719/// struct Rug(#[table] Foo);
720///
721/// ```
722/// Had we used [`Proxy<Foo>`](Proxy) as our start value here (and given up having
723/// a self parameter), we could've used the proxies themselves to check
724/// for uniqueness, avoiding the need to compare and clone [`String`] fields,
725/// and removing any chance of a name collision.
726/// ```rust
727/// use persian_rug::{contextual, persian_rug, Accessor, Context, Contextual, Proxy};
728/// use std::collections::BTreeSet;
729///
730/// #[contextual(Rug)]
731/// struct Foo {
732///    id: String,
733///    links: Vec<Proxy<Foo>>
734/// }
735///
736/// impl Foo {
737///   pub fn print_graph<A: Accessor<Context=Rug>>(start: Proxy<Foo>, access: A) {
738///     let mut b = BTreeSet::new();
739///     let mut work = Vec::new();
740///     work.push(start);
741///     while let Some(item_proxy) = work.pop() {
742///       let item = access.get(&item_proxy);
743///       println!("{}", item.id);
744///       b.insert(item_proxy);
745///       for link in &item.links {
746///         if !b.contains(link) {
747///           work.push(*link);
748///         }
749///       }
750///     }
751///   }
752/// }
753///
754/// #[persian_rug]
755/// struct Rug(#[table] Foo);
756///
757/// ```
758///
759/// Note that a [`Proxy`] implements [`Copy`] as well as [`Eq`]. The
760/// implementation of [`Ord`] is guaranteed to be consistent on a given
761/// run of the program, but no other guarantees are made.
762pub struct Proxy<T> {
763    _marker: core::marker::PhantomData<T>,
764    index: u64,
765}
766
767impl<T> Clone for Proxy<T> {
768    fn clone(&self) -> Self {
769        *self
770    }
771}
772
773impl<T> Copy for Proxy<T> {}
774
775impl<T> PartialOrd for Proxy<T> {
776    fn partial_cmp(&self, other: &Proxy<T>) -> Option<Ordering> {
777        Some(self.cmp(other))
778    }
779}
780
781impl<T> Ord for Proxy<T> {
782    fn cmp(&self, other: &Proxy<T>) -> Ordering {
783        self.index.cmp(&other.index)
784    }
785}
786
787impl<T> PartialEq for Proxy<T> {
788    fn eq(&self, other: &Proxy<T>) -> bool {
789        self.index.eq(&other.index)
790    }
791}
792
793impl<T> Eq for Proxy<T> {}
794
795impl<T> Hash for Proxy<T> {
796    fn hash<H: Hasher>(&self, state: &mut H) {
797        self.index.hash(state);
798    }
799}
800
801impl<T> std::fmt::Debug for Proxy<T> {
802    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
803        write!(
804            f,
805            "persian_rug::Proxy<{}> {{ handle: {} }}",
806            std::any::type_name::<T>(),
807            self.index
808        )
809    }
810}
811
812/// A dense set of [`Proxy`] objects
813///
814/// This is a dense bit-set of [`Proxy`] objects, where each existing
815/// object is represented by a single bit. Whether this representation
816/// makes sense in a given application depends upon how many objects
817/// of type `T` you have created proxies for, and what proportion will
818/// typically belong to the set. In many cases, other set
819/// representations like [`BTreeSet`](std::collections::BTreeSet) and
820/// [`HashSet`](std::collections::HashSet) will be preferable.
821///
822/// The driver for this type is graph search, where it may be that this
823/// representation is smaller, lighter and faster than those set types,
824/// and we have a need to both query efficiently and to store very large
825/// numbers of sets.
826///
827/// Usage is straightforward:
828///
829/// ```rust
830/// use persian_rug::{contextual, persian_rug, Context, ProxySet};
831///
832/// #[contextual(Foo)]
833/// struct Bar {
834///   name: String,
835/// }
836///
837/// #[persian_rug]
838/// struct Foo(#[table] Bar);
839///
840/// let mut foo = Foo(Default::default());
841/// let a = foo.add(Bar { name: "A".to_string() });
842/// let b = foo.add(Bar { name: "B".to_string() });
843/// let c = foo.add(Bar { name: "C".to_string() });
844///
845/// let mut s = ProxySet::new();
846/// s.insert(a);
847/// s.insert(c);
848///
849/// assert!(s.contains(&a));
850/// assert!(!s.contains(&b));
851/// assert!(s.contains(&c));
852/// ```
853#[derive(Debug)]
854pub struct ProxySet<T> {
855    _marker: core::marker::PhantomData<T>,
856    marks: Vec<u64>,
857    len: usize,
858}
859
860impl<T> ProxySet<T> {
861    pub fn new() -> Self {
862        Self {
863            _marker: Default::default(),
864            marks: Vec::new(),
865            len: 0,
866        }
867    }
868
869    fn word(index: u64) -> usize {
870        (index >> 6) as usize
871    }
872    fn bit(index: u64) -> u64 {
873        1u64 << (index & 0x3F)
874    }
875
876    pub fn insert(&mut self, p: Proxy<T>) {
877        if self.marks.len() <= Self::word(p.index) {
878            self.marks.resize(Self::word(p.index) + 1, 0u64);
879        }
880        if self.marks[Self::word(p.index)] & Self::bit(p.index) == 0 {
881            self.marks[Self::word(p.index)] |= Self::bit(p.index);
882            self.len += 1;
883        }
884    }
885
886    pub fn contains(&self, p: &Proxy<T>) -> bool {
887        if self.marks.len() <= Self::word(p.index) {
888            false
889        } else {
890            self.marks[Self::word(p.index)] & (Self::bit(p.index)) != 0
891        }
892    }
893
894    pub fn remove(&mut self, p: &Proxy<T>) -> Option<Proxy<T>> {
895        if self.marks.len() <= Self::word(p.index) {
896            None
897        } else if self.marks[Self::word(p.index)] & (Self::bit(p.index)) != 0 {
898            self.marks[Self::word(p.index)] &= !(Self::bit(p.index));
899            self.len -= 1;
900            Some(*p)
901        } else {
902            None
903        }
904    }
905
906    pub fn len(&self) -> usize {
907        self.len
908    }
909
910    pub fn is_empty(&self) -> bool {
911        self.len == 0
912    }
913
914    pub fn iter(&self) -> ProxySetIterator<'_, T> {
915        ProxySetIterator {
916            _marker: Default::default(),
917            index: 0,
918            mask: 0,
919            owner: self,
920        }
921    }
922}
923
924impl<T> Default for ProxySet<T> {
925    fn default() -> Self {
926        Self::new()
927    }
928}
929
930impl<T> Clone for ProxySet<T> {
931    fn clone(&self) -> Self {
932        Self {
933            _marker: Default::default(),
934            marks: self.marks.clone(),
935            len: self.len,
936        }
937    }
938}
939
940impl<T> PartialEq for ProxySet<T> {
941    fn eq(&self, other: &Self) -> bool {
942        self.marks == other.marks
943    }
944}
945
946impl<T> Eq for ProxySet<T> {}
947
948impl<T> PartialOrd for ProxySet<T> {
949    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
950        Some(self.cmp(other))
951    }
952}
953
954impl<T> Ord for ProxySet<T> {
955    fn cmp(&self, other: &Self) -> Ordering {
956        self.marks.cmp(&other.marks)
957    }
958}
959
960impl<T> Hash for ProxySet<T> {
961    fn hash<H: Hasher>(&self, state: &mut H) {
962        self.marks.hash(state)
963    }
964}
965
966/// An [`Iterator`] over members of a [`ProxySet`].
967///
968/// This is returned by [`ProxySet::iter()`]. Note that the returned
969/// [`Proxy`] objects are not references, since there are no actual
970/// proxy objects stored in the [`ProxySet`].
971pub struct ProxySetIterator<'a, T> {
972    _marker: core::marker::PhantomData<T>,
973    index: u64,
974    mask: u64,
975    owner: &'a ProxySet<T>,
976}
977
978impl<'a, T> Iterator for ProxySetIterator<'a, T> {
979    type Item = Proxy<T>;
980
981    fn next(&mut self) -> Option<Proxy<T>> {
982        while self.owner.marks.len() > ProxySet::<T>::word(self.index) {
983            let w = self.owner.marks[ProxySet::<T>::word(self.index)];
984            if w ^ self.mask == 0 {
985                self.index = ((self.index >> 6) + 1) << 6;
986                self.mask = 0;
987            } else if w & ProxySet::<T>::bit(self.index) != 0 {
988                self.mask |= ProxySet::<T>::bit(self.index);
989                self.index += 1;
990                if self.index & 0x3F == 0 {
991                    self.mask = 0;
992                }
993                return Some(Proxy {
994                    _marker: Default::default(),
995                    index: self.index - 1,
996                });
997            } else {
998                self.index += 1;
999                if self.index & 0x3F == 0 {
1000                    self.mask = 0;
1001                }
1002            }
1003        }
1004        None
1005    }
1006}
1007
1008/// A holder for [`Contextual`] objects.
1009///
1010/// It is unlikely that you will ever need to instantiate this class,
1011/// unless for some reason the [`persian_rug`] attribute macro which
1012/// creates [`Context`] implementations is not suitable for your use.
1013///
1014/// A context object will generally have one table per object type,
1015/// and that table does the work of storing, retrieving and iterating
1016/// over objects of that type, and the [`Proxy`] objects that refer to
1017/// them.
1018#[derive(Clone, Debug)]
1019pub struct Table<T> {
1020    members: BTreeMap<u64, T>,
1021    proxies: Vec<Proxy<T>>,
1022    next_index: u64,
1023}
1024
1025impl<T> Default for Table<T> {
1026    fn default() -> Self {
1027        Self {
1028            members: Default::default(),
1029            proxies: Default::default(),
1030            next_index: Default::default(),
1031        }
1032    }
1033}
1034
1035impl<T> Table<T> {
1036    /// Create a new table.
1037    ///
1038    /// Tables are created empty.
1039    pub fn new() -> Self {
1040        Default::default()
1041    }
1042
1043    /// Insert a new item.
1044    ///
1045    /// The return value is a [`Proxy`] that you can store, and later
1046    /// use to retrieve the stored object from the table.
1047    pub fn push(&mut self, value: T) -> Proxy<T> {
1048        let ix = self.next_index;
1049        self.next_index += 1;
1050        self.members.insert(ix, value);
1051        let p = Proxy {
1052            _marker: Default::default(),
1053            index: ix,
1054        };
1055        self.proxies.push(p);
1056        p
1057    }
1058
1059    /// Retrieve a previously stored item.
1060    ///
1061    /// Note that the return value is an [`Option`], because not all
1062    /// [`Proxy`] objects of a given type can be necessarily retrieved
1063    /// from a given [`Table`]. This is clearly the ideal however, and
1064    /// [`Context`] implementations created with the [`persian_rug`]
1065    /// attribute macro unwrap this return value, causing a panic on
1066    /// failure.
1067    pub fn get(&self, p: &Proxy<T>) -> Option<&T> {
1068        self.members.get(&p.index)
1069    }
1070
1071    /// Retrieve a previously stored item mutably.
1072    ///
1073    /// Note that the return value is an [`Option`], because not all
1074    /// [`Proxy`] objects of a given type can be necessarily retrieved
1075    /// from a given [`Table`]. This is clearly the ideal however, and
1076    /// [`Context`] implementations created with the [`persian_rug`]
1077    /// attribute macro unwrap this return value, causing a panic on
1078    /// failure.
1079    pub fn get_mut(&mut self, p: &Proxy<T>) -> Option<&mut T> {
1080        self.members.get_mut(&p.index)
1081    }
1082
1083    /// Iterate over shared references to all stored items.
1084    pub fn iter(&self) -> TableIterator<T> {
1085        TableIterator {
1086            iter: self.members.values(),
1087        }
1088    }
1089
1090    /// Iterate over mutable references to all stored items.
1091    pub fn iter_mut(&mut self) -> TableMutIterator<T> {
1092        TableMutIterator {
1093            iter: self.members.values_mut(),
1094        }
1095    }
1096
1097    /// Iterate over proxies for all stored items.
1098    ///
1099    /// Note that [`Proxy`] implements [`Copy`] so that although this
1100    /// returns references, you can cheaply convert them to owned
1101    /// values as required with the [`copied`][Iterator::copied]
1102    /// method on [`Iterator`].
1103    pub fn iter_proxies(&self) -> TableProxyIterator<T> {
1104        TableProxyIterator {
1105            iter: self.proxies.iter(),
1106        }
1107    }
1108}
1109
1110/// An [`Iterator`] over references to [`Contextual`] objects.
1111pub struct TableIterator<'a, T> {
1112    iter: std::collections::btree_map::Values<'a, u64, T>,
1113}
1114
1115impl<'a, T> Iterator for TableIterator<'a, T> {
1116    type Item = &'a T;
1117    fn next(&mut self) -> Option<Self::Item> {
1118        self.iter.next()
1119    }
1120}
1121
1122/// An [`Iterator`] over references to [`Proxy`] objects for [`Contextual`]
1123/// objects.
1124pub struct TableProxyIterator<'a, T> {
1125    iter: std::slice::Iter<'a, Proxy<T>>,
1126}
1127
1128impl<'a, T> Iterator for TableProxyIterator<'a, T> {
1129    type Item = &'a Proxy<T>;
1130    fn next(&mut self) -> Option<Self::Item> {
1131        self.iter.next()
1132    }
1133}
1134
1135/// An [`Iterator`] over exclusive references to [`Contextual`] objects.
1136pub struct TableMutIterator<'a, T> {
1137    iter: std::collections::btree_map::ValuesMut<'a, u64, T>,
1138}
1139
1140impl<'a, T> Iterator for TableMutIterator<'a, T> {
1141    type Item = &'a mut T;
1142    fn next(&mut self) -> Option<Self::Item> {
1143        self.iter.next()
1144    }
1145}
1146
1147pub use persian_rug_derive::{constraints, contextual, persian_rug};