Skip to main content

test_fork_core/
sugar.rs

1// Copyright (C) 2025-2026 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, Eq, Debug)]
40pub struct ForkId(TypeId);
41
42impl ForkId {
43    #[doc(hidden)]
44    pub fn of(id: TypeId) -> Self {
45        Self(id)
46    }
47}
48
49impl Display for ForkId {
50    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
51        let mut hasher = DefaultHasher::default();
52        self.0.hash(&mut hasher);
53        write!(f, ":{:016X}", hasher.finish())
54    }
55}
56
57
58#[cfg(test)]
59mod test {
60    use super::*;
61
62
63    /// Check that IDs created for the same type are considered equal.
64    #[test]
65    fn ids_for_same_type_are_equal() {
66        struct UniqueType;
67        let id1 = ForkId::of(TypeId::of::<UniqueType>());
68        let id2 = ForkId::of(TypeId::of::<UniqueType>());
69        assert_eq!(id1, id2);
70        assert_eq!(id1.to_string(), id2.to_string());
71    }
72
73    #[test]
74    fn ids_are_actually_distinct() {
75        let id1 = fork_id!();
76        let id2 = fork_id!();
77        assert_ne!(id1, id2);
78        assert_ne!(id1.to_string(), id2.to_string());
79    }
80}