appcore_capabilities/
selection.rs1use appcore_core::{CapabilityDescriptor, CoreId};
12use appcore_distributed_contracts::PeerRecord;
13
14#[derive(Debug, Clone, PartialEq, Eq)]
16pub enum CapabilityProvider {
17 Local {
19 core_id: CoreId,
21 descriptor: CapabilityDescriptor,
23 },
24 Remote {
26 peer: Box<PeerRecord>,
28 descriptor: CapabilityDescriptor,
30 preferred: bool,
32 },
33}
34
35impl CapabilityProvider {
36 pub fn descriptor(&self) -> &CapabilityDescriptor {
38 match self {
39 Self::Local { descriptor, .. } | Self::Remote { descriptor, .. } => descriptor,
40 }
41 }
42
43 pub fn core_id(&self) -> &CoreId {
45 match self {
46 Self::Local { core_id, .. } => core_id,
47 Self::Remote { peer, .. } => &peer.identity.core_id,
48 }
49 }
50
51 pub fn is_remote(&self) -> bool {
53 matches!(self, Self::Remote { .. })
54 }
55}
56
57#[derive(Debug, Clone, Copy, PartialEq, Eq)]
59pub struct ResolutionPolicy {
60 pub prefer_local: bool,
62 pub allow_remote: bool,
64}
65
66impl Default for ResolutionPolicy {
67 fn default() -> Self {
68 Self {
69 prefer_local: true,
70 allow_remote: true,
71 }
72 }
73}
74
75pub trait CapabilitySelectionPolicy: Send + Sync {
77 fn select(&self, candidates: &[CapabilityProvider]) -> Option<CapabilityProvider>;
79}
80
81#[derive(Debug, Clone, Copy, Default)]
83pub struct DefaultCapabilitySelectionPolicy {
84 pub policy: ResolutionPolicy,
86}
87
88impl CapabilitySelectionPolicy for DefaultCapabilitySelectionPolicy {
89 fn select(&self, candidates: &[CapabilityProvider]) -> Option<CapabilityProvider> {
90 if self.policy.prefer_local {
91 if let Some(local) = candidates
92 .iter()
93 .find(|candidate| matches!(candidate, CapabilityProvider::Local { .. }))
94 {
95 return Some(local.clone());
96 }
97 }
98
99 if self.policy.allow_remote {
100 if let Some(remote) = candidates.iter().find(|candidate| {
101 matches!(
102 candidate,
103 CapabilityProvider::Remote {
104 preferred: true,
105 ..
106 }
107 )
108 }) {
109 return Some(remote.clone());
110 }
111
112 if let Some(remote) = candidates
113 .iter()
114 .find(|candidate| matches!(candidate, CapabilityProvider::Remote { .. }))
115 {
116 return Some(remote.clone());
117 }
118 }
119
120 candidates
121 .iter()
122 .find(|candidate| matches!(candidate, CapabilityProvider::Local { .. }))
123 .cloned()
124 }
125}