grafos_std/
affinity.rs

1//! Typed affinity constraints for lease builders (Phase 48.11).
2//!
3//! See `docs/spec/affinity-request-model.md` for the wire format and
4//! `docs/grafos/affinity-taxonomy.md` for the canonical taxonomy.
5//!
6//! These types mirror `fabricbios_core::lease_affinity` at the SDK layer.
7//! When passed to [`CpuBuilder::affinity`](crate::cpu::CpuBuilder::affinity)
8//! or [`GpuBuilder::affinity`](crate::gpu::GpuBuilder::affinity), the
9//! runtime emits `TLV_LEASE_AFFINITY` (0x0910) entries on the `LEASE_ALLOC`
10//! request.
11
12use alloc::string::String;
13
14/// Affinity strength.
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub enum Strength {
17    /// Hard constraint — placement fails if unsatisfiable.
18    Required,
19    /// Soft hint — boosts score for matching candidates.
20    Preferred,
21}
22
23/// Affinity target — what the constraint is relative to.
24#[derive(Debug, Clone, PartialEq, Eq)]
25pub enum Target {
26    /// A specific node.
27    Node(u128),
28    /// A specific rack (topology affinity).
29    Rack(u32),
30    /// A trust domain name (trust affinity).
31    TrustDomain(String),
32}
33
34impl Target {
35    /// Shorthand for a node target.
36    pub fn node(id: u128) -> Self {
37        Self::Node(id)
38    }
39
40    /// Shorthand for a rack target.
41    pub fn rack(id: u32) -> Self {
42        Self::Rack(id)
43    }
44
45    /// Shorthand for a trust domain target.
46    pub fn trust_domain(name: impl Into<String>) -> Self {
47        Self::TrustDomain(name.into())
48    }
49}
50
51/// A typed affinity constraint.
52///
53/// # Examples
54///
55/// ```rust
56/// use grafos_std::affinity::{Affinity, Strength, Target};
57///
58/// // Required: place on node 42.
59/// let a = Affinity::new(Strength::Required, Target::node(42));
60///
61/// // Preferred anti-affinity: avoid rack 7.
62/// let b = Affinity::anti(Strength::Preferred, Target::rack(7));
63///
64/// // Required trust domain.
65/// let c = Affinity::new(Strength::Required, Target::trust_domain("secure-enclave"));
66/// ```
67#[derive(Debug, Clone, PartialEq, Eq)]
68pub struct Affinity {
69    pub strength: Strength,
70    pub target: Target,
71    pub anti: bool,
72}
73
74impl Affinity {
75    /// Create an affinity constraint (toward the target).
76    pub fn new(strength: Strength, target: Target) -> Self {
77        Self {
78            strength,
79            target,
80            anti: false,
81        }
82    }
83
84    /// Create an anti-affinity constraint (away from the target).
85    pub fn anti(strength: Strength, target: Target) -> Self {
86        Self {
87            strength,
88            target,
89            anti: true,
90        }
91    }
92}