test_fork_core/
sugar.rs

1// Copyright (C) 2025 Daniel Mueller <deso@posteo.net>
2// SPDX-License-Identifier: (Apache-2.0 OR MIT)
3
4//-
5// Copyright 2018 Jason Lingle
6//
7// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
8// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
9// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
10// option. This file may not be copied, modified, or distributed
11// except according to those terms.
12
13use std::any::TypeId;
14use std::fmt::Display;
15use std::fmt::Formatter;
16use std::fmt::Result as FmtResult;
17use std::hash::DefaultHasher;
18use std::hash::Hash as _;
19use std::hash::Hasher;
20
21
22/// Produce a hashable identifier unique to the particular macro invocation
23/// which is stable across processes of the same executable.
24///
25/// This is usually the best thing to pass for the `fork_id` argument of
26/// [`fork`][crate::fork].
27///
28/// The type of the expression this macro expands to is [`ForkId`].
29#[macro_export]
30macro_rules! fork_id {
31    () => {{
32        struct _ForkId;
33        &std::string::ToString::to_string(&$crate::ForkId::of(::std::any::TypeId::of::<_ForkId>()))
34    }};
35}
36
37
38/// The type of the value produced by [`fork_id!`].
39#[derive(Clone, Hash, PartialEq, Debug)]
40pub struct ForkId(TypeId);
41
42impl ForkId {
43    #[allow(missing_docs)]
44    #[doc(hidden)]
45    pub fn of(id: TypeId) -> Self {
46        ForkId(id)
47    }
48}
49
50impl Display for ForkId {
51    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
52        let mut hasher = DefaultHasher::default();
53        self.0.hash(&mut hasher);
54        write!(f, ":{:016X}", hasher.finish())
55    }
56}
57
58
59#[cfg(test)]
60mod test {
61    use super::*;
62
63
64    /// Check that IDs created for the same type are considered equal.
65    #[test]
66    fn ids_for_same_type_are_equal() {
67        struct UniqueType;
68        let id1 = ForkId::of(TypeId::of::<UniqueType>());
69        let id2 = ForkId::of(TypeId::of::<UniqueType>());
70        assert_eq!(id1, id2);
71        assert_eq!(id1.to_string(), id2.to_string());
72    }
73
74    #[test]
75    fn ids_are_actually_distinct() {
76        let id1 = fork_id!();
77        let id2 = fork_id!();
78        assert_ne!(id1, id2);
79        assert_ne!(id1.to_string(), id2.to_string());
80    }
81}