use serde::{Deserialize, Serialize};
use crate::Principal;
pub const CAP_SCOPES_V1: &str = "scopes/v1";
pub const SCOPE_SYNC_OP: &str = "scope.sync";
pub const SCOPE_DESCRIBE_OP: &str = "scope.describe";
pub const MAX_LIVE_SCOPES_PER_OWNER: usize = 10_000;
pub const MAX_SCOPE_ATTRIBUTE_BYTES: usize = 4 * 1024;
pub const MAX_SCOPE_TOMBSTONES_PER_OWNER: usize = 1_000;
pub const MAX_CARRIER_TARGETS: usize = 16;
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)]
#[serde(rename_all = "snake_case")]
pub enum ScopeKind {
Head,
Worker,
Ephemeral,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(deny_unknown_fields)]
pub struct ScopeParent {
pub owner: Principal,
#[serde(rename = "ref")]
pub scope_ref: String,
pub scope_epoch: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(deny_unknown_fields)]
pub struct ScopeCarrier {
pub principal: Principal,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub targets: Option<Vec<String>>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
#[serde(deny_unknown_fields)]
pub struct ScopeAttributes {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub agent_id: Option<String>,
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub delegates: bool,
}
impl ScopeAttributes {
pub fn is_empty(&self) -> bool {
self.agent_id.is_none() && !self.delegates
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(deny_unknown_fields)]
pub struct ScopeRecord {
#[serde(rename = "ref")]
pub scope_ref: String,
pub scope_epoch: u64,
pub kind: ScopeKind,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub parent: Option<ScopeParent>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub child_owners: Vec<Principal>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub carriers: Vec<ScopeCarrier>,
#[serde(default, skip_serializing_if = "ScopeAttributes::is_empty")]
pub attributes: ScopeAttributes,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(deny_unknown_fields)]
pub struct ScopeSelector {
pub owner: Principal,
#[serde(rename = "ref")]
pub scope_ref: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub scope_epoch: Option<u64>,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)]
#[serde(rename_all = "snake_case")]
pub enum ParentState {
Linked,
Pending,
Ended,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum ScopeRecordOutcome {
Created,
Replaced,
Updated,
Unchanged,
Refused,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct ScopeRecordResult {
#[serde(rename = "ref")]
pub scope_ref: String,
pub scope_epoch: u64,
pub outcome: ScopeRecordOutcome,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub code: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub message: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub version: Option<u64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub parent_state: Option<ParentState>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct ScopeEnded {
#[serde(rename = "ref")]
pub scope_ref: String,
pub scope_epoch: u64,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum ScopeStatus {
Live,
Ended,
NotLive,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct ScopeStamp {
pub owner: Principal,
#[serde(rename = "ref")]
pub scope_ref: String,
pub scope_epoch: u64,
pub kind: ScopeKind,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub parent: Option<ScopeParent>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub parent_state: Option<ParentState>,
#[serde(default, skip_serializing_if = "ScopeAttributes::is_empty")]
pub attributes: ScopeAttributes,
pub owner_authorized: bool,
}