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}