1use serde::{Deserialize, Serialize};
2
3#[cfg(feature = "ts-rs")]
4use ts_rs::TS;
5
6use crate::common::{Id, ScopeIds, Timestamp};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
10#[cfg_attr(feature = "ts-rs", derive(TS), ts(export, export_to = "../bindings/"))]
11#[serde(rename_all = "snake_case")]
12pub enum PinTargetType {
13 Observation,
14 Summary,
15}
16
17impl PinTargetType {
18 pub const ALL: &'static [PinTargetType] = &[PinTargetType::Observation, PinTargetType::Summary];
19}
20
21#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
25#[cfg_attr(feature = "ts-rs", derive(TS), ts(export, export_to = "../bindings/"))]
26#[serde(rename_all = "camelCase")]
27pub struct Pin {
28 pub id: Id,
29 pub target_type: PinTargetType,
30 pub target_id: Id,
31 #[serde(default, skip_serializing_if = "Option::is_none")]
32 #[cfg_attr(feature = "ts-rs", ts(optional))]
33 pub reason: Option<String>,
34 #[cfg_attr(feature = "ts-rs", ts(type = "number"))]
35 pub created_at: Timestamp,
36 #[serde(default, skip_serializing_if = "Option::is_none")]
37 #[cfg_attr(feature = "ts-rs", ts(optional, type = "number"))]
38 pub expires_at: Option<Timestamp>,
39 pub scope_ids: ScopeIds,
40}
41
42#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
44#[cfg_attr(feature = "ts-rs", derive(TS), ts(export, export_to = "../bindings/"))]
45#[serde(rename_all = "camelCase")]
46pub struct PinInput {
47 #[serde(default, skip_serializing_if = "Option::is_none")]
48 #[cfg_attr(feature = "ts-rs", ts(optional))]
49 pub id: Option<Id>,
50 pub target_type: PinTargetType,
51 pub target_id: Id,
52 #[serde(default, skip_serializing_if = "Option::is_none")]
53 #[cfg_attr(feature = "ts-rs", ts(optional))]
54 pub reason: Option<String>,
55 #[serde(default, skip_serializing_if = "Option::is_none")]
56 #[cfg_attr(feature = "ts-rs", ts(optional, type = "number"))]
57 pub created_at: Option<Timestamp>,
58 #[serde(default, skip_serializing_if = "Option::is_none")]
59 #[cfg_attr(feature = "ts-rs", ts(optional, type = "number"))]
60 pub expires_at: Option<Timestamp>,
61 pub scope_ids: ScopeIds,
62}
63
64pub fn is_pin_active(pin: &Pin, now: Timestamp) -> bool {
66 match pin.expires_at {
67 None => true,
68 Some(exp) => exp > now,
69 }
70}