Skip to content

Commit 998f47e

Browse files
committed
rune: Improve docs
1 parent cce2845 commit 998f47e

File tree

10 files changed

+295
-29
lines changed

10 files changed

+295
-29
lines changed

crates/rune-alloc/src/lib.rs

-2
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,8 @@
3636
#![no_std]
3737
#![deny(rustdoc::broken_intra_doc_links)]
3838
#![deny(rustdoc::private_doc_tests)]
39-
#![cfg_attr(rune_nightly, deny(rustdoc::missing_doc_code_examples))]
4039
#![cfg_attr(rune_nightly, allow(internal_features))]
4140
#![cfg_attr(rune_nightly, feature(fmt_internals))]
42-
#![cfg_attr(rune_nightly, feature(rustdoc_missing_doc_code_examples))]
4341
#![cfg_attr(rune_nightly, feature(core_intrinsics))]
4442
#![cfg_attr(rune_nightly, feature(dropck_eyepatch))]
4543
#![cfg_attr(rune_nightly, feature(min_specialization))]

crates/rune-core/src/hash.rs

+219-8
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,37 @@ mod to_type_hash;
66

77
use core::fmt;
88
use core::hash::{BuildHasher, BuildHasherDefault, Hash as _, Hasher};
9+
use core::num::NonZero;
910

1011
#[cfg(feature = "musli")]
1112
use musli::{Decode, Encode};
1213
use serde::{Deserialize, Serialize};
1314
use twox_hash::XxHash64;
1415

16+
/// Error raised when too many parameters are added to a [`ParametersBuilder`].
17+
///
18+
/// # Examples
19+
///
20+
/// ```
21+
/// use rune::TypeHash;
22+
/// use rune::hash::ParametersBuilder;
23+
///
24+
/// let mut params = ParametersBuilder::new();
25+
///
26+
/// let err = 'outer: {
27+
/// for _ in 0.. {
28+
/// params = match params.add(i64::HASH) {
29+
/// Ok(params) => params,
30+
/// Err(err) => break 'outer err,
31+
/// };
32+
/// };
33+
///
34+
/// panic!("expected error");
35+
/// };
36+
///
37+
/// let err = err.to_string();
38+
/// # Ok::<_, rune::hash::TooManyParameters>(())
39+
/// ```
1540
#[derive(Debug)]
1641
#[non_exhaustive]
1742
pub struct TooManyParameters;
@@ -75,13 +100,90 @@ const PARAMETERS: [u64; 32] = [
75100

76101
/// The primitive hash that among other things is used to reference items,
77102
/// types, and native functions.
103+
///
104+
/// # Examples
105+
///
106+
/// ```
107+
/// use rune::Hash;
108+
///
109+
/// assert!(Hash::index(0).as_non_empty().is_some());
110+
/// ```
111+
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
112+
#[cfg_attr(feature = "musli", derive(Decode, Encode), musli(transparent))]
113+
#[repr(transparent)]
114+
pub struct NonZeroHash(#[doc(hidden)] pub NonZero<u64>);
115+
116+
impl NonZeroHash {
117+
/// Get the value as a hash.
118+
///
119+
/// # Examples
120+
///
121+
/// ```
122+
/// use rune::Hash;
123+
///
124+
/// let hash = Hash::index(0).as_non_empty().ok_or("expected non-empty")?;
125+
/// assert_eq!(hash.get(), Hash::index(0));
126+
/// # Ok::<_, &'static str>(())
127+
/// ```
128+
pub const fn get(self) -> Hash {
129+
Hash(self.0.get())
130+
}
131+
}
132+
133+
impl TryClone for NonZeroHash {
134+
#[inline]
135+
fn try_clone(&self) -> alloc::Result<Self> {
136+
Ok(*self)
137+
}
138+
}
139+
140+
impl fmt::Display for NonZeroHash {
141+
#[inline]
142+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
143+
write!(f, "0x{:x}", self.0.get())
144+
}
145+
}
146+
147+
impl fmt::Debug for NonZeroHash {
148+
#[inline]
149+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
150+
write!(f, "0x{:x}", self.0.get())
151+
}
152+
}
153+
154+
impl PartialEq<Hash> for NonZeroHash {
155+
#[inline]
156+
fn eq(&self, other: &Hash) -> bool {
157+
self.0.get() == other.0
158+
}
159+
}
160+
161+
/// The primitive hash that among other things is used to reference items,
162+
/// types, and native functions.
163+
///
164+
/// # Examples
165+
///
166+
/// ```
167+
/// use rune::Hash;
168+
///
169+
/// assert_ne!(Hash::index(0), Hash::index(1));
170+
/// ```
78171
#[derive(Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
79172
#[cfg_attr(feature = "musli", derive(Decode, Encode), musli(transparent))]
80173
#[repr(transparent)]
81174
pub struct Hash(#[doc(hidden)] pub u64);
82175

83176
impl Hash {
84177
/// The empty hash.
178+
///
179+
/// # Examples
180+
///
181+
/// ```
182+
/// use rune::Hash;
183+
///
184+
/// assert_ne!(Hash::index(0), Hash::EMPTY);
185+
/// assert!(Hash::EMPTY.as_non_empty().is_none());
186+
/// ```
85187
pub const EMPTY: Self = Self(0);
86188

87189
/// Construct a new raw hash.
@@ -97,13 +199,18 @@ impl Hash {
97199
}
98200

99201
/// Return the current hash if it is non-empty.
202+
///
203+
/// # Examples
204+
///
205+
/// ```
206+
/// use rune::Hash;
207+
///
208+
/// assert!(Hash::index(0).as_non_empty().is_some());
209+
/// assert!(Hash::EMPTY.as_non_empty().is_none());
210+
/// ```
100211
#[inline]
101-
pub fn as_non_empty(&self) -> Option<Self> {
102-
if self.is_empty() {
103-
None
104-
} else {
105-
Some(*self)
106-
}
212+
pub fn as_non_empty(&self) -> Option<NonZeroHash> {
213+
Some(NonZeroHash(NonZero::new(self.0)?))
107214
}
108215

109216
/// Coerce a hash into its inner numerical value.
@@ -119,26 +226,60 @@ impl Hash {
119226
}
120227

121228
/// Construct a hash from an index.
229+
///
230+
/// # Examples
231+
///
232+
/// ```
233+
/// use rune::Hash;
234+
///
235+
/// assert_ne!(Hash::index(0), Hash::index(1));
236+
/// ```
122237
#[inline]
123238
pub fn index(index: usize) -> Self {
124239
Self(INDEX ^ (index as u64))
125240
}
126241

127242
/// Get the hash corresponding to a string identifier like `function` or
128243
/// `hello_world`.
244+
///
245+
/// # Examples
246+
///
247+
/// ```
248+
/// use rune::Hash;
249+
///
250+
/// assert_ne!(Hash::ident("foo"), Hash::index(0));
251+
/// ```
129252
pub fn ident(name: &str) -> Hash {
130253
let mut hasher = Self::new_hasher();
131254
name.hash(&mut hasher);
132255
Self(IDENT ^ hasher.finish())
133256
}
134257

135258
/// Get the hash of a type.
259+
///
260+
/// # Examples
261+
///
262+
/// ```
263+
/// use rune::Hash;
264+
///
265+
/// assert!(!Hash::type_hash(["main"]).is_empty());
266+
/// assert!(!Hash::type_hash(["main", "other"]).is_empty());
267+
/// ```
136268
pub fn type_hash(path: impl ToTypeHash) -> Self {
137269
path.to_type_hash()
138270
}
139271

140272
/// Construct a hash to an instance function, where the instance is a
141273
/// pre-determined type.
274+
///
275+
/// # Examples
276+
///
277+
/// ```
278+
/// use rune::Hash;
279+
/// use rune::runtime::Protocol;
280+
///
281+
/// assert!(!Hash::associated_function("main", &Protocol::INTO_TYPE_NAME).is_empty());
282+
/// ```
142283
#[inline]
143284
pub fn associated_function(type_hash: impl IntoHash, name: impl IntoHash) -> Self {
144285
let type_hash = type_hash.into_hash();
@@ -147,13 +288,31 @@ impl Hash {
147288
}
148289

149290
/// Construct a hash corresponding to a field function.
291+
///
292+
/// # Examples
293+
///
294+
/// ```
295+
/// use rune::{Hash, TypeHash};
296+
/// use rune::runtime::Protocol;
297+
///
298+
/// assert!(!Hash::field_function(&Protocol::ADD, i64::HASH, "field").is_empty());
299+
/// ```
150300
#[inline]
151301
pub fn field_function(protocol: impl IntoHash, type_hash: Hash, name: impl IntoHash) -> Self {
152302
let protocol = protocol.into_hash();
153303
Self::associated_function(Hash(type_hash.0 ^ protocol.0), name)
154304
}
155305

156306
/// Construct an index function.
307+
///
308+
/// # Examples
309+
///
310+
/// ```
311+
/// use rune::{Hash, TypeHash};
312+
/// use rune::runtime::Protocol;
313+
///
314+
/// assert!(!Hash::index_function(&Protocol::ADD, i64::HASH, Hash::index(1)).is_empty());
315+
/// ```
157316
#[inline]
158317
pub fn index_function(protocol: impl IntoHash, type_hash: Hash, index: Hash) -> Self {
159318
let protocol = protocol.into_hash();
@@ -170,8 +329,7 @@ impl Hash {
170329
/// Hash the given iterator of object keys.
171330
pub fn object_keys<I>(keys: I) -> Self
172331
where
173-
I: IntoIterator,
174-
I::Item: AsRef<str>,
332+
I: IntoIterator<Item: AsRef<str>>,
175333
{
176334
let mut hasher = Self::new_hasher();
177335
OBJECT_KEYS.hash(&mut hasher);
@@ -226,18 +384,21 @@ impl Hash {
226384
}
227385

228386
impl TryClone for Hash {
387+
#[inline]
229388
fn try_clone(&self) -> alloc::Result<Self> {
230389
Ok(*self)
231390
}
232391
}
233392

234393
impl fmt::Display for Hash {
394+
#[inline]
235395
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
236396
write!(f, "0x{:x}", self.0)
237397
}
238398
}
239399

240400
impl fmt::Debug for Hash {
401+
#[inline]
241402
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
242403
write!(f, "0x{:x}", self.0)
243404
}
@@ -273,6 +434,19 @@ pub struct ParametersBuilder {
273434

274435
impl ParametersBuilder {
275436
/// Construct a new collection of parameters.
437+
///
438+
/// # Examples
439+
///
440+
/// ```
441+
/// use rune::{Hash, TypeHash};
442+
/// use rune::hash::ParametersBuilder;
443+
///
444+
/// let mut params = ParametersBuilder::new();
445+
///
446+
/// let hash = params.finish();
447+
/// assert_eq!(hash, Hash::EMPTY);
448+
/// # Ok::<_, rune::hash::TooManyParameters>(())
449+
/// ```
276450
pub const fn new() -> Self {
277451
Self {
278452
base: 0,
@@ -286,6 +460,21 @@ impl ParametersBuilder {
286460
/// # Errors
287461
///
288462
/// Errors if too many parameters are added.
463+
///
464+
/// # Examples
465+
///
466+
/// ```
467+
/// use rune::TypeHash;
468+
/// use rune::hash::ParametersBuilder;
469+
///
470+
/// let mut params = ParametersBuilder::new();
471+
///
472+
/// let params = params.add(String::HASH)?;
473+
/// let params = params.add(i64::HASH)?;
474+
///
475+
/// let hash = params.finish();
476+
/// # Ok::<_, rune::hash::TooManyParameters>(())
477+
/// ```
289478
pub const fn add(mut self, Hash(hash): Hash) -> Result<Self, TooManyParameters> {
290479
if self.index >= PARAMETERS.len() {
291480
self.shift += 8;
@@ -302,7 +491,29 @@ impl ParametersBuilder {
302491
}
303492

304493
/// Finish building the parameters hash.
494+
///
495+
/// # Examples
496+
///
497+
/// ```
498+
/// use rune::TypeHash;
499+
/// use rune::hash::ParametersBuilder;
500+
///
501+
/// let mut params = ParametersBuilder::new();
502+
///
503+
/// let params = params.add(String::HASH)?;
504+
/// let params = params.add(i64::HASH)?;
505+
///
506+
/// let hash = params.finish();
507+
/// # Ok::<_, rune::hash::TooManyParameters>(())
508+
/// ```
305509
pub const fn finish(self) -> Hash {
306510
Hash::new(self.base)
307511
}
308512
}
513+
514+
impl PartialEq<NonZeroHash> for Hash {
515+
#[inline]
516+
fn eq(&self, other: &NonZeroHash) -> bool {
517+
self.0 == other.0.get()
518+
}
519+
}

crates/rune-core/src/hash/into_hash.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ mod sealed {
1414
impl<T, const N: usize> Sealed for Params<T, N> {}
1515
}
1616

17-
/// Trait for types which can be converted into a
18-
/// [Hash][struct@crate::hash::Hash].
17+
/// Trait for types which can be converted into a [Hash].
18+
///
19+
/// [Hash]: struct@crate::hash::Hash
1920
pub trait IntoHash: self::sealed::Sealed {
2021
/// Convert current type into a hash.
2122
fn into_hash(self) -> Hash;

0 commit comments

Comments
 (0)