Skip to content

Commit 6ddfef1

Browse files
authored
[15/n] add remaining docs, warn on missing docs
Fill in the last few docs and add some more examples. Reviewers: andrewjstone Reviewed By: andrewjstone Pull Request: #46
1 parent 0496884 commit 6ddfef1

File tree

6 files changed

+210
-20
lines changed

6 files changed

+210
-20
lines changed

daft-derive/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ mod internals;
66

77
use syn::parse_macro_input;
88

9+
// NOTE: We do not define documentation here -- only in daft while re-exporting
10+
// these items. This is so that doctests that depend on daft work.
11+
912
#[proc_macro_derive(Diffable, attributes(daft))]
1013
pub fn derive_diffable(
1114
input: proc_macro::TokenStream,

daft/src/alloc_impls.rs

+84-2
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,90 @@ impl<T: Diffable + ?Sized> Diffable for Rc<T> {
5757
}
5858
}
5959

60-
map_diff!((BTreeMap, Ord));
61-
set_diff!((BTreeSet, Ord));
60+
map_diff!(
61+
/// A diff of two [`BTreeMap`] instances.
62+
///
63+
/// The diff contains three elements:
64+
///
65+
/// - `common`: Entries that are present in both maps, with their values
66+
/// stored as a [`Leaf`].
67+
/// - `added`: Entries present in `after`, but not in `before`.
68+
/// - `removed`: Entries present in `before`, but not in `after`.
69+
///
70+
/// If `V` implements `Eq`, `common` can be split into
71+
/// [`unchanged`][Self::unchanged] and [`modified`][Self::modified] entries.
72+
/// Additionally, if `V` implements [`Diffable`],
73+
/// [`modified_diff`][Self::modified_diff] can be used to recursively diff
74+
/// modified entries.
75+
///
76+
/// # Example
77+
///
78+
/// ```
79+
/// # #[cfg(feature = "std")] {
80+
/// use daft::{BTreeMapDiff, Diffable, Leaf};
81+
/// use std::collections::BTreeMap;
82+
///
83+
/// let a: BTreeMap<usize, &str> =
84+
/// [(0, "lorem"), (1, "ipsum"), (2, "dolor")].into_iter().collect();
85+
/// let b: BTreeMap<usize, &str> =
86+
/// [(1, "ipsum"), (2, "sit"), (3, "amet")].into_iter().collect();
87+
///
88+
/// let changes = a.diff(&b);
89+
/// let expected = BTreeMapDiff {
90+
/// // Keys are stored by reference and matched by equality.
91+
/// common: [
92+
/// (&1, Leaf { before: &"ipsum", after: &"ipsum" }),
93+
/// (&2, Leaf { before: &"dolor", after: &"sit" }),
94+
/// ].into_iter().collect(),
95+
/// added: [(&3, &"amet")].into_iter().collect(),
96+
/// removed: [(&0, &"lorem")].into_iter().collect(),
97+
/// };
98+
///
99+
/// assert_eq!(changes, expected);
100+
///
101+
/// // If the values are `Eq`, it's also possible to get lists of
102+
/// // modified and unchanged entries.
103+
/// let unchanged = changes.unchanged().collect::<Vec<_>>();
104+
/// let modified = changes.modified().collect::<Vec<_>>();
105+
///
106+
/// assert_eq!(unchanged, [(&1, &"ipsum")]);
107+
/// assert_eq!(modified, [(&2, Leaf { before: &"dolor", after: &"sit" })]);
108+
/// # }
109+
/// ```
110+
BTreeMap, Ord
111+
);
112+
set_diff!(
113+
/// A diff of two [`BTreeSet`] instances.
114+
///
115+
/// The diff contains three elements:
116+
///
117+
/// - `common`: Entries that are present in both sets.
118+
/// - `added`: Entries present in `after`, but not in `before`.
119+
/// - `removed`: Entries present in `before`, but not in `after`.
120+
///
121+
/// # Example
122+
///
123+
/// ```
124+
/// # #[cfg(feature = "std")] {
125+
/// use daft::{BTreeSetDiff, Diffable};
126+
/// use std::collections::BTreeSet;
127+
///
128+
/// let a: BTreeSet<usize> = [0, 1].into_iter().collect();
129+
/// let b: BTreeSet<usize> = [1, 2].into_iter().collect();
130+
///
131+
/// let changes = a.diff(&b);
132+
/// let expected = BTreeSetDiff {
133+
/// // Entries are stored by reference and matched by equality.
134+
/// common: [&1].into_iter().collect(),
135+
/// added: [&2].into_iter().collect(),
136+
/// removed: [&0].into_iter().collect(),
137+
/// };
138+
///
139+
/// assert_eq!(changes, expected);
140+
/// # }
141+
/// ```
142+
BTreeSet, Ord
143+
);
62144

63145
/// Treat Vecs as Leafs
64146
//

daft/src/leaf.rs

+3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ use core::ops::{Deref, DerefMut};
88
/// For more information, see the [crate-level documentation](crate).
99
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1010
pub struct Leaf<T> {
11+
/// The value on the before side.
1112
pub before: T,
13+
14+
/// The value on the after side.
1215
pub after: T,
1316
}
1417

daft/src/lib.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![cfg_attr(doc_cfg, feature(doc_auto_cfg))]
2+
#![warn(missing_docs)]
23
#![cfg_attr(not(feature = "std"), no_std)]
34

45
//! Daft is a library to perform semantic diffs of Rust data structures.
@@ -495,7 +496,18 @@ mod third_party;
495496

496497
#[cfg(feature = "alloc")]
497498
pub use alloc_impls::*;
498-
pub use daft_derive::*;
499+
/// Derive macro for the [`Diffable`] trait.
500+
///
501+
/// The behavior of this macro varies by type:
502+
///
503+
/// - For **structs**, this macro generates a corresponding recursive (eager)
504+
/// diff type by default. A non-recursive (lazy) diff can be generated by
505+
/// annotating the struct overall with `#[daft(leaf)]`.
506+
/// - For **enums** and **unions**, this macro generates a non-recursive (lazy)
507+
/// diff.
508+
///
509+
/// For more information, see the [crate-level documentation](crate).
510+
pub use daft_derive::Diffable;
499511
pub use diffable::*;
500512
pub use leaf::*;
501513
#[cfg(feature = "std")]

daft/src/macros.rs

+21-15
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,25 @@ macro_rules! leaf_deref {
4040
/// This is supported for `BTreeMap` and `HashMap`
4141
#[cfg(feature = "alloc")]
4242
macro_rules! map_diff {
43-
($(($typ:ident, $key_constraint:ident)),*) => {
44-
$(
43+
($(#[$doc:meta])* $typ:ident, $key_constraint:ident) => {
4544
paste::paste! {
46-
45+
$(#[$doc])*
4746
#[derive(Debug, PartialEq, Eq)]
4847
pub struct [<$typ Diff>]<'daft, K: $key_constraint + Eq, V> {
48+
/// Entries common to both maps.
49+
///
50+
/// Values are stored as `Leaf`s to references.
4951
pub common: $typ<&'daft K, $crate::Leaf<&'daft V>>,
52+
53+
/// Entries present in the `after` map, but not in `before`.
5054
pub added: $typ<&'daft K, &'daft V>,
55+
56+
/// Entries present in the `before` map, but not in `after`.
5157
pub removed: $typ<&'daft K, &'daft V>,
5258
}
5359

5460
impl<'daft, K: $key_constraint + Eq, V> [<$typ Diff>]<'daft, K, V> {
61+
#[doc = "Create a new, empty `" $typ "Diff` instance."]
5562
pub fn new() -> Self {
5663
Self {
5764
common: $typ::new(),
@@ -160,31 +167,32 @@ macro_rules! map_diff {
160167
diff
161168
}
162169
}
163-
164170
}
165-
)*
166171
}
167172
}
168173

169174
/// Create a type `<SetType>Diff` and `impl Diffable` on it.
170175
///
171-
/// This is supported for `BTreeSet` and `HashSet`
172-
/// We use Vecs rather than sets internally to avoid requiring key constraints
173-
/// on `Leafs`
176+
/// This is supported for `BTreeSet` and `HashSet`.
174177
#[cfg(feature = "alloc")]
175178
macro_rules! set_diff {
176-
($(($typ:ident, $key_constraint:ident)),*) => {
177-
$(
178-
paste::paste! {
179-
179+
($(#[$doc:meta])* $typ:ident, $key_constraint:ident) => {
180+
paste::paste! {
181+
$(#[$doc])*
180182
#[derive(Debug, PartialEq, Eq)]
181-
pub struct [<$typ Diff>]<'daft, K: $key_constraint + Eq> {
183+
pub struct [<$typ Diff>]<'daft, K: $key_constraint + Eq> {
184+
/// Entries common to both sets.
182185
pub common: $typ<&'daft K>,
186+
187+
/// Entries present in the `after` set, but not in `before`.
183188
pub added: $typ<&'daft K>,
189+
190+
/// Entries present in the `before` set, but not in `after`.
184191
pub removed: $typ<&'daft K>,
185192
}
186193

187194
impl<'daft, K: $key_constraint + Eq> [<$typ Diff>]<'daft, K> {
195+
#[doc = "Create a new, empty `" $typ "Diff` instance."]
188196
pub fn new() -> Self {
189197
Self {
190198
common: $typ::new(),
@@ -215,8 +223,6 @@ macro_rules! set_diff {
215223
diff
216224
}
217225
}
218-
219226
}
220-
)*
221227
}
222228
}

daft/src/std_impls.rs

+86-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,92 @@ use std::{
1111
leaf! { Path, OsStr }
1212
leaf_deref! { PathBuf => Path, OsString => OsStr }
1313

14-
map_diff!((HashMap, Hash));
15-
set_diff!((HashSet, Hash));
14+
map_diff!(
15+
/// A diff of two [`HashMap`] instances.
16+
///
17+
/// The diff contains three elements:
18+
///
19+
/// - `common`: Entries that are present in both maps, with their values
20+
/// stored as a [`Leaf`][crate::Leaf].
21+
/// - `added`: Entries present in `after`, but not in `before`.
22+
/// - `removed`: Entries present in `before`, but not in `after`.
23+
///
24+
/// If `V` implements `Eq`, `common` can be split into
25+
/// [`unchanged`][Self::unchanged] and [`modified`][Self::modified] entries.
26+
/// Additionally, if `V` implements [`Diffable`],
27+
/// [`modified_diff`][Self::modified_diff] can be used to recursively diff
28+
/// modified entries.
29+
///
30+
/// # Example
31+
///
32+
/// ```
33+
/// # #[cfg(feature = "std")] {
34+
/// use daft::{Diffable, HashMapDiff, Leaf};
35+
/// use std::collections::HashMap;
36+
///
37+
/// let a: HashMap<usize, &str> =
38+
/// [(0, "lorem"), (1, "ipsum"), (2, "dolor")].into_iter().collect();
39+
/// let b: HashMap<usize, &str> =
40+
/// [(1, "ipsum"), (2, "sit"), (3, "amet")].into_iter().collect();
41+
///
42+
/// let changes = a.diff(&b);
43+
/// let expected = HashMapDiff {
44+
/// // Keys are stored by reference and matched by equality.
45+
/// common: [
46+
/// (&1, Leaf { before: &"ipsum", after: &"ipsum" }),
47+
/// (&2, Leaf { before: &"dolor", after: &"sit" }),
48+
/// ].into_iter().collect(),
49+
/// added: [(&3, &"amet")].into_iter().collect(),
50+
/// removed: [(&0, &"lorem")].into_iter().collect(),
51+
/// };
52+
///
53+
/// assert_eq!(changes, expected);
54+
///
55+
/// // If the values are `Eq`, it's also possible to get lists of
56+
/// // modified and unchanged entries.
57+
/// let mut unchanged = changes.unchanged().collect::<Vec<_>>();
58+
/// unchanged.sort_by_key(|(k, _)| *k);
59+
/// let mut modified = changes.modified().collect::<Vec<_>>();
60+
/// modified.sort_by_key(|(k, _)| *k);
61+
///
62+
/// assert_eq!(unchanged, [(&1, &"ipsum")]);
63+
/// assert_eq!(modified, [(&2, Leaf { before: &"dolor", after: &"sit" })]);
64+
/// # }
65+
/// ```
66+
HashMap, Hash
67+
);
68+
set_diff!(
69+
/// A diff of two [`HashSet`] instances.
70+
///
71+
/// The diff contains three elements:
72+
///
73+
/// - `common`: Entries that are present in both sets.
74+
/// - `added`: Entries present in `after`, but not in `before`.
75+
/// - `removed`: Entries present in `before`, but not in `after`.
76+
///
77+
/// # Example
78+
///
79+
/// ```
80+
/// # #[cfg(feature = "std")] {
81+
/// use daft::{Diffable, HashSetDiff};
82+
/// use std::collections::HashSet;
83+
///
84+
/// let a: HashSet<usize> = [0, 1].into_iter().collect();
85+
/// let b: HashSet<usize> = [1, 2].into_iter().collect();
86+
///
87+
/// let changes = a.diff(&b);
88+
/// let expected = HashSetDiff {
89+
/// // Entries are stored by reference and matched by equality.
90+
/// common: [&1].into_iter().collect(),
91+
/// added: [&2].into_iter().collect(),
92+
/// removed: [&0].into_iter().collect(),
93+
/// };
94+
///
95+
/// assert_eq!(changes, expected);
96+
/// # }
97+
/// ```
98+
HashSet, Hash
99+
);
16100

17101
#[cfg(test)]
18102
mod tests {

0 commit comments

Comments
 (0)