1use std::path::PathBuf;
2use serde_json::{Map, Value};
3use cyfs_base::*;
4use cyfs_bdt::{
5 TempSeq,
6 ChunkCodecDesc,
7};
8use super::{
9 bdt_request::BdtDataRefererInfo
10};
11
12pub struct InterestHandlerRequest {
13 pub session_id: TempSeq,
14 pub chunk: ChunkId,
15 pub prefer_type: ChunkCodecDesc,
16 pub from: Option<DeviceId>,
17 pub referer: Option<BdtDataRefererInfo>,
18 pub from_channel: DeviceId,
19 pub group_path: Option<String>
20}
21
22
23impl JsonCodec<InterestHandlerRequest> for InterestHandlerRequest {
24 fn encode_json(&self) -> Map<String, Value> {
25 let mut obj = Map::new();
26 JsonCodecHelper::encode_number_field(&mut obj, "session_id", self.session_id.value());
27 JsonCodecHelper::encode_string_field(&mut obj, "chunk", &self.chunk);
28 JsonCodecHelper::encode_field(&mut obj, "prefer_type", &self.prefer_type);
29 JsonCodecHelper::encode_option_string_field(&mut obj, "from", self.from.as_ref());
30 JsonCodecHelper::encode_option_field(&mut obj, "referer", self.referer.as_ref());
31 JsonCodecHelper::encode_string_field(&mut obj, "from_channel", &self.from_channel);
32 JsonCodecHelper::encode_option_string_field(&mut obj, "group_path", self.group_path.as_ref());
33 obj
34 }
35
36 fn decode_json(obj: &Map<String, Value>) -> BuckyResult<Self> {
37 let session_id: u32 = JsonCodecHelper::decode_int_field(obj, "session_id")?;
38 Ok(Self {
39 session_id: TempSeq::from(session_id),
40 chunk: JsonCodecHelper::decode_string_field(obj, "chunk")?,
41 prefer_type: JsonCodecHelper::decode_field(obj, "prefer_type")?,
42 from: JsonCodecHelper::decode_option_string_field(obj, "from")?,
43 referer: JsonCodecHelper::decode_option_field(obj, "referer")?,
44 from_channel: JsonCodecHelper::decode_string_field(obj, "from_channel")?,
45 group_path: JsonCodecHelper::decode_option_string_field(obj, "group_path")?,
46 })
47 }
48}
49
50
51impl std::fmt::Display for InterestHandlerRequest {
52 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
53 write!(f, "session_id: {:?}", self.session_id)?;
54 write!(f, ", chunk: {}", self.chunk)?;
55 write!(f, ", prefer_type: {:?}", self.prefer_type)?;
56 if let Some(from) = &self.from {
57 write!(f, ", from: {}", from)?;
58 }
59 if let Some(referer) = &self.referer {
60 write!(f, ", referer: {}", referer)?;
61 }
62 if let Some(group_path) = &self.group_path {
63 write!(f, ", group_path: {}", group_path)?;
64 }
65 write!(f, ", from_channel: {:?}", self.from_channel)
66
67 }
68}
69
70
71#[derive(Clone)]
72pub struct RespInterestFields {
73 pub err: BuckyErrorCode,
74 pub redirect: Option<DeviceId>,
75 pub redirect_referer_target: Option<ObjectId>,
76}
77
78impl std::fmt::Display for RespInterestFields {
79 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
80 write!(f, "err: {}", self.err)?;
81 if let Some(redierct) = &self.redirect {
82 write!(f, ", redierct: {}", redierct)?;
83 }
84 if let Some(obj_id) = &self.redirect_referer_target {
85 write!(f, ", redirect_referer_target: {}", obj_id)?;
86 }
87 Ok(())
88 }
89}
90
91
92impl JsonCodec<RespInterestFields> for RespInterestFields {
93 fn encode_json(&self) -> Map<String, Value> {
94 let mut obj = Map::new();
95 let err: u32 = self.err.into();
96 JsonCodecHelper::encode_number_field(&mut obj, "err", err);
97 JsonCodecHelper::encode_option_string_field(&mut obj, "redirect", self.redirect.as_ref());
98 JsonCodecHelper::encode_option_string_field(&mut obj, "redirect_referer_target", self.redirect_referer_target.as_ref());
99 obj
100 }
101
102 fn decode_json(obj: &Map<String, Value>) -> BuckyResult<Self> {
103 let err: u32 = JsonCodecHelper::decode_int_field(obj, "err")?;
104 Ok(Self {
105 err: BuckyErrorCode::from(err),
106 redirect: JsonCodecHelper::decode_option_string_field(obj, "redirect")?,
107 redirect_referer_target: JsonCodecHelper::decode_option_string_field(obj, "decode_option_string_field")?,
108 })
109 }
110}
111
112#[derive(Debug, Clone)]
113pub enum InterestUploadSource {
114 ChunkStore,
115 File {
116 path: PathBuf,
117 offset: u64
118 }
119}
120
121#[derive(Clone)]
122pub enum InterestHandlerResponse {
123 Default,
124 Upload {
125 source: InterestUploadSource,
126 groups: Vec<String>
127 },
128 Transmit(DeviceId),
129 Resp(RespInterestFields),
130 Handled
131}
132
133impl InterestHandlerResponse {
134 pub fn type_str(&self) -> &str {
135 match self {
136 Self::Default => "Default",
137 Self::Upload {..} => "Upload",
138 Self::Transmit(_) => "Transmit",
139 Self::Resp(_) => "Resp",
140 Self::Handled => "Handled"
141 }
142 }
143
144 pub fn resp_interest(&self) -> Option<&RespInterestFields> {
145 if let Self::Resp(resp) = self {
146 Some(resp)
147 } else {
148 None
149 }
150 }
151
152 pub fn transmit_to(&self) -> Option<&DeviceId> {
153 if let Self::Transmit(to) = self {
154 Some(to)
155 } else {
156 None
157 }
158 }
159}
160
161impl JsonCodec<InterestHandlerResponse> for InterestHandlerResponse {
162 fn encode_json(&self) -> Map<String, Value> {
163 let mut obj = Map::new();
164 match self {
165 Self::Default => JsonCodecHelper::encode_string_field(&mut obj, "type", "Default"),
166 Self::Upload { source, groups }=> {
167 JsonCodecHelper::encode_string_field(&mut obj, "type", "Upload");
168 JsonCodecHelper::encode_str_array_field(&mut obj, "upload_groups", groups);
169 match source {
170 InterestUploadSource::ChunkStore => {},
171 InterestUploadSource::File { path, offset } => {
172 JsonCodecHelper::encode_option_string_field(&mut obj, "upload_from_path", path.to_str());
173 JsonCodecHelper::encode_option_number_field(&mut obj, "upload_from_offset", Some(*offset));
174 }
175 }
176
177 },
178 Self::Transmit(to) => {
179 JsonCodecHelper::encode_string_field(&mut obj, "type", "Transmit");
180 JsonCodecHelper::encode_option_string_field(&mut obj, "transmit_to", Some(to));
181 },
182 Self::Resp(resp) => {
183 JsonCodecHelper::encode_string_field(&mut obj, "type", "Resp");
184 JsonCodecHelper::encode_option_field(&mut obj, "resp", Some(resp));
185 },
186 Self::Handled => JsonCodecHelper::encode_string_field(&mut obj, "type", "Handled")
187 }
188 obj
189 }
190
191 fn decode_json(obj: &Map<String, Value>) -> BuckyResult<Self> {
192 let type_str: String = JsonCodecHelper::decode_string_field(obj, "type")?;
193 match type_str.as_str() {
194 "Default" => Ok(Self::Default),
195 "Upload" => {
196 let groups = JsonCodecHelper::decode_str_array_field(obj, "upload_groups")?;
197 let source = if let Some(path) = JsonCodecHelper::decode_option_string_field(obj, "upload_from_path")? {
198 let offset = JsonCodecHelper::decode_option_int_field(obj, "upload_from_offset")?.unwrap_or_default();
199 InterestUploadSource::File { path, offset }
200 } else {
201 InterestUploadSource::ChunkStore
202 };
203 Ok(Self::Upload { source, groups })
204 },
205 "Transmit" => Ok(Self::Transmit(JsonCodecHelper::decode_option_string_field(obj, "transmit_to")?
206 .ok_or_else(|| BuckyError::new(BuckyErrorCode::InvalidInput, "no transmit_to field"))?)),
207 "Resp" => Ok(Self::Resp(JsonCodecHelper::decode_option_field(obj, "resp")?
208 .ok_or_else(|| BuckyError::new(BuckyErrorCode::InvalidInput, "no resp field"))?)),
209 "Handled" => Ok(Self::Handled),
210 _ => Err(BuckyError::new(BuckyErrorCode::InvalidInput, format!("invalid type {}", type_str)))
211 }
212 }
213}
214
215
216impl std::fmt::Display for InterestHandlerResponse {
217 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
218 match self {
219 Self::Default => write!(f, "Default")?,
220 Self::Upload { source, groups } => write!(f, "Upload{{groups:{:?},source:{:?}}}", groups, source)?,
221 Self::Transmit(to) => write!(f, "Transmit({})", to)?,
222 Self::Resp(resp) => write!(f, "Resp({})", resp)?,
223 Self::Handled => write!(f, "Handled")?
224 }
225 Ok(())
226 }
227}
228