forked from ucan-wg/rs-ucan
/
revoke.rs
111 lines (92 loc) · 3.05 KB
/
revoke.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
//! This is an ability for revoking [`Delegation`][crate::delegation::Delegation]s by their [`Cid`].
//!
//! For more, see the [UCAN Revocation spec](https://github.com/ucan-wg/revocation).
use crate::{
ability::{arguments, command::Command},
invocation::promise,
ipld,
};
use libipld_core::{cid::Cid, ipld::Ipld};
use serde::{Deserialize, Serialize};
use std::fmt::Debug;
/// The fully resolved variant: ready to execute.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Revoke {
/// The UCAN to revoke
pub ucan: Cid,
// FIXME pub witness
}
impl From<Revoke> for arguments::Named<Ipld> {
fn from(revoke: Revoke) -> Self {
arguments::Named::from_iter([("ucan".to_string(), Ipld::Link(revoke.ucan).into())])
}
}
const COMMAND: &'static str = "/ucan/revoke";
impl Command for Revoke {
const COMMAND: &'static str = COMMAND;
}
impl Command for PromisedRevoke {
const COMMAND: &'static str = COMMAND;
}
impl TryFrom<arguments::Named<Ipld>> for Revoke {
type Error = ();
fn try_from(arguments: arguments::Named<Ipld>) -> Result<Self, Self::Error> {
let ipld: Ipld = arguments.get("ucan").ok_or(())?.clone();
let nt: ipld::cid::Newtype = ipld.try_into().map_err(|_| ())?;
Ok(Revoke { ucan: nt.cid })
}
}
impl promise::Resolvable for Revoke {
type Promised = PromisedRevoke;
}
impl From<PromisedRevoke> for arguments::Named<ipld::Promised> {
fn from(promised: PromisedRevoke) -> Self {
arguments::Named::from_iter([("ucan".into(), Ipld::from(promised.ucan).into())])
}
}
/// A variant where arguments may be [`Promise`][crate::invocation::promise]s.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PromisedRevoke {
pub ucan: promise::Any<Cid>,
}
impl TryFrom<arguments::Named<ipld::Promised>> for PromisedRevoke {
type Error = ();
fn try_from(arguments: arguments::Named<ipld::Promised>) -> Result<Self, Self::Error> {
let mut ucan = None;
for (k, prom) in arguments {
match k.as_str() {
"ucan" => match Ipld::try_from(prom) {
Ok(Ipld::Link(cid)) => {
ucan = Some(promise::Any::Resolved(cid));
}
Err(pending) => ucan = Some(pending.into()),
_ => return Err(()),
},
_ => (),
}
}
Ok(PromisedRevoke {
ucan: ucan.ok_or(())?,
})
}
}
impl From<Revoke> for PromisedRevoke {
fn from(r: Revoke) -> PromisedRevoke {
PromisedRevoke {
ucan: promise::Any::Resolved(r.ucan),
}
}
}
impl From<PromisedRevoke> for arguments::Named<Ipld> {
fn from(p: PromisedRevoke) -> arguments::Named<Ipld> {
arguments::Named::from_iter([("ucan".into(), p.ucan.into())])
}
}
impl TryFrom<PromisedRevoke> for Revoke {
type Error = ();
fn try_from(p: PromisedRevoke) -> Result<Self, Self::Error> {
Ok(Revoke {
ucan: p.ucan.try_resolve().map_err(|_| ())?,
})
}
}