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};