Skip to main content

pedant_core/resolution/rust/
identity.rs

1//! Opaque, project-scoped identities.
2//!
3//! Every identity carries the canonical-root fingerprint and the manifest
4//! revision of the project that issued it, so an identity from one project can
5//! never select a record in another project that happens to share a local
6//! index.
7
8use std::fmt;
9
10/// The root fingerprint and manifest revision that scope every issued identity.
11#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
12pub(super) struct ProjectAuthority {
13    root: [u8; 32],
14    revision: [u8; 32],
15}
16
17impl ProjectAuthority {
18    /// Bind a canonical-root fingerprint to a manifest revision.
19    pub(super) fn new(root: [u8; 32], revision: [u8; 32]) -> Self {
20        Self { root, revision }
21    }
22
23    /// Whether both authorities describe the same canonical repository root.
24    pub(super) fn same_root(&self, other: &Self) -> bool {
25        self.root == other.root
26    }
27
28    /// Whether both authorities describe the same manifest revision.
29    pub(super) fn same_revision(&self, other: &Self) -> bool {
30        self.revision == other.revision
31    }
32}
33
34/// Opaque identity of a Cargo package inside one loaded project.
35#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
36pub struct PackageId {
37    authority: ProjectAuthority,
38    index: u32,
39}
40
41impl PackageId {
42    /// Issue an identity for the package at `index`.
43    pub(super) fn new(authority: ProjectAuthority, index: u32) -> Self {
44        Self { authority, index }
45    }
46
47    /// The issuing project's authority.
48    pub(super) fn authority(&self) -> ProjectAuthority {
49        self.authority
50    }
51
52    /// The project-local index this identity selects.
53    pub(super) fn index(&self) -> u32 {
54        self.index
55    }
56}
57
58impl fmt::Debug for PackageId {
59    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
60        write_identity(formatter, "PackageId", self.index)
61    }
62}
63
64/// Opaque identity of a Cargo target inside one loaded project.
65#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
66pub struct TargetId {
67    authority: ProjectAuthority,
68    index: u32,
69}
70
71impl TargetId {
72    /// Issue an identity for the target at `index`.
73    pub(super) fn new(authority: ProjectAuthority, index: u32) -> Self {
74        Self { authority, index }
75    }
76
77    /// The issuing project's authority.
78    pub(super) fn authority(&self) -> ProjectAuthority {
79        self.authority
80    }
81
82    /// The project-local index this identity selects.
83    pub(super) fn index(&self) -> u32 {
84        self.index
85    }
86}
87
88impl fmt::Debug for TargetId {
89    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
90        write_identity(formatter, "TargetId", self.index)
91    }
92}
93
94/// Render an identity without exposing its scoping fingerprints.
95fn write_identity(formatter: &mut fmt::Formatter<'_>, label: &str, index: u32) -> fmt::Result {
96    write!(formatter, "{label}({index})")
97}
98
99/// The slice position one stored index names.
100///
101/// Every index this crate stores is a `u32`, and every slice it reads is
102/// addressed by `usize`. On a target where `usize` is narrower than `u32` the
103/// saturating answer selects no element, which each caller already treats as
104/// absence.
105pub(super) fn index_of(value: u32) -> usize {
106    usize::try_from(value).unwrap_or(usize::MAX)
107}
108
109/// The stored index one slice position is recorded as.
110///
111/// The saturating answer names no record, which each caller reports rather
112/// than resolves.
113pub(super) fn position(value: usize) -> u32 {
114    u32::try_from(value).unwrap_or(u32::MAX)
115}