1mod pinner;
17mod store;
18
19pub use pinner::*;
20pub use store::*;
21
22use thiserror::Error;
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
26pub enum PinMode {
27 Direct,
29 Recursive,
31 Indirect,
33}
34
35impl PinMode {
36 pub fn parse(s: &str) -> Option<Self> {
38 match s.to_lowercase().as_str() {
39 "direct" => Some(PinMode::Direct),
40 "recursive" => Some(PinMode::Recursive),
41 "indirect" => Some(PinMode::Indirect),
42 "all" => None, _ => None,
44 }
45 }
46
47 pub fn as_str(&self) -> &'static str {
49 match self {
50 PinMode::Direct => "direct",
51 PinMode::Recursive => "recursive",
52 PinMode::Indirect => "indirect",
53 }
54 }
55}
56
57impl std::fmt::Display for PinMode {
58 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59 write!(f, "{}", self.as_str())
60 }
61}
62
63#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
65pub struct PinInfo {
66 pub cid: String,
68 pub mode: PinMode,
70 pub name: Option<String>,
72}
73
74#[derive(Debug, Error)]
76pub enum PinError {
77 #[error("Block not found: {0}")]
78 BlockNotFound(String),
79
80 #[error("CID not pinned: {0}")]
81 NotPinned(String),
82
83 #[error("CID already pinned: {0}")]
84 AlreadyPinned(String),
85
86 #[error("Cannot unpin indirect pin directly: {0}")]
87 CannotUnpinIndirect(String),
88
89 #[error("Blockstore error: {0}")]
90 Blockstore(#[from] ferripfs_blockstore::BlockstoreError),
91
92 #[error("IO error: {0}")]
93 Io(#[from] std::io::Error),
94
95 #[error("JSON error: {0}")]
96 Json(#[from] serde_json::Error),
97
98 #[error("CID parse error: {0}")]
99 CidParse(String),
100
101 #[error("Pin verification failed: {0}")]
102 VerificationFailed(String),
103}
104
105pub type PinResult<T> = Result<T, PinError>;
107
108#[cfg(test)]
109mod tests {
110 use super::*;
111
112 #[test]
113 fn test_pin_mode_from_str() {
114 assert_eq!(PinMode::parse("direct"), Some(PinMode::Direct));
115 assert_eq!(PinMode::parse("recursive"), Some(PinMode::Recursive));
116 assert_eq!(PinMode::parse("indirect"), Some(PinMode::Indirect));
117 assert_eq!(PinMode::parse("all"), None);
118 assert_eq!(PinMode::parse("invalid"), None);
119 }
120
121 #[test]
122 fn test_pin_mode_display() {
123 assert_eq!(PinMode::Direct.to_string(), "direct");
124 assert_eq!(PinMode::Recursive.to_string(), "recursive");
125 assert_eq!(PinMode::Indirect.to_string(), "indirect");
126 }
127}