cyfs_lib/ndn/
input_request.rs

1use super::def::*;
2use crate::base::NDNDataRequestRange;
3use crate::*;
4use cyfs_base::*;
5
6use async_std::io::Read;
7use std::any::Any;
8use std::fmt;
9use std::fmt::Display;
10use std::str::FromStr;
11use std::sync::Arc;
12
13pub type NDNInputRequestUserData = Arc<dyn Any + Sync + Send + 'static>;
14
15#[derive(Clone, Debug)]
16pub struct NDNInputRequestCommon {
17    // 请求路径,可为空
18    pub req_path: Option<String>,
19
20    pub source: RequestSourceInfo,
21
22    // api级别
23    pub level: NDNAPILevel,
24
25    // 需要处理数据的关联对象,主要用以chunk
26    pub referer_object: Vec<NDNDataRefererObject>,
27
28    // 用以处理默认行为
29    pub target: Option<ObjectId>,
30
31    pub flags: u32,
32
33    // input链的自定义数据
34    pub user_data: Option<NDNInputRequestUserData>,
35}
36
37impl NDNInputRequestCommon {
38    pub fn check_param_with_referer(&self, object_id: &ObjectId) -> BuckyResult<()> {
39        match object_id.obj_type_code() {
40            ObjectTypeCode::Chunk => {
41                for item in &self.referer_object {
42                    match item.object_id.obj_type_code() {
43                        ObjectTypeCode::File => {
44                            if !item.is_inner_path_empty() {
45                                let msg = format!("ndn referer_object is file but inner_path is not empty! obj={}, referer={}", 
46                                object_id, item);
47                                error!("{}", msg);
48                                return Err(BuckyError::new(BuckyErrorCode::InvalidParam, msg));
49                            }
50                        }
51                        ObjectTypeCode::Dir => {}
52                        ObjectTypeCode::ObjectMap => {
53                            if item.is_inner_path_empty() {
54                                let msg = format!("ndn referer_object is object_map but inner_path is empty! obj={}, referer={}", object_id, item);
55                                error!("{}", msg);
56                                return Err(BuckyError::new(BuckyErrorCode::InvalidParam, msg));
57                            }
58                        }
59                        t @ _ => {
60                            let msg = format!("unsupport ndn referer_object type for chunk! chunk={}, referer={}, type={:?}", 
61                            object_id, item, t);
62                            error!("{}", msg);
63                            return Err(BuckyError::new(BuckyErrorCode::InvalidParam, msg));
64                        }
65                    }
66                }
67            }
68            ObjectTypeCode::File => {
69                for item in &self.referer_object {
70                    match item.object_id.obj_type_code() {
71                        ObjectTypeCode::Dir | ObjectTypeCode::ObjectMap => {
72                            if item.is_inner_path_empty() {
73                                let msg = format!("ndn referer_object is dir or object_map but inner_path is empty! obj={}, referer={}", 
74                                object_id, item);
75                                error!("{}", msg);
76                                return Err(BuckyError::new(BuckyErrorCode::InvalidParam, msg));
77                            }
78                        }
79                        t @ _ => {
80                            let msg = format!("unsupport ndn referer_object type for file! obj={}, referer={}, type={:?}", 
81                            object_id, item, t);
82                            error!("{}", msg);
83                            return Err(BuckyError::new(BuckyErrorCode::InvalidParam, msg));
84                        }
85                    }
86                }
87            }
88            ObjectTypeCode::Dir | ObjectTypeCode::ObjectMap => {
89                if self.referer_object.len() > 0 {
90                    let msg = format!(
91                        "ndn referer_object not support for dir/object_map! obj={}, type={:?}",
92                        object_id,
93                        object_id.obj_type_code()
94                    );
95                    error!("{}", msg);
96                    return Err(BuckyError::new(BuckyErrorCode::InvalidParam, msg));
97                }
98            }
99            t @ _ => {
100                let msg = format!(
101                    "unsupport ndn object_id type! obj={}, type={:?}",
102                    object_id, t,
103                );
104                error!("{}", msg);
105                return Err(BuckyError::new(BuckyErrorCode::InvalidParam, msg));
106            }
107        }
108
109        Ok(())
110    }
111}
112
113impl fmt::Display for NDNInputRequestCommon {
114    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115        write!(f, "req_path: {:?}", self.req_path)?;
116        write!(f, ", {}", self.source)?;
117        write!(f, ", level: {}", self.level.to_string())?;
118
119        if let Some(target) = &self.target {
120            write!(f, ", target: {}", target.to_string())?;
121        }
122
123        if !self.referer_object.is_empty() {
124            write!(f, ", referer_object: {:?}", self.referer_object)?;
125        }
126
127        write!(f, ", flags: {}", self.flags)?;
128
129        Ok(())
130    }
131}
132
133#[derive(Copy, Clone, Eq, PartialEq)]
134pub enum NDNDataType {
135    Mem,
136    SharedMem,
137}
138
139impl Display for NDNDataType {
140    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
141        write!(
142            f,
143            "{}",
144            match self {
145                Self::Mem => "memory",
146                Self::SharedMem => "shared_memory",
147            }
148        )
149    }
150}
151
152impl FromStr for NDNDataType {
153    type Err = BuckyError;
154
155    fn from_str(s: &str) -> Result<Self, Self::Err> {
156        Ok(match s {
157            "memory" => Self::Mem,
158            "shared_memory" => Self::SharedMem,
159            v @ _ => {
160                let msg = format!("unknown ndn data type: {}", v);
161                error!("{}", msg);
162
163                return Err(BuckyError::new(BuckyErrorCode::InvalidData, msg));
164            }
165        })
166    }
167}
168/*
169chunk_id
170file_id
171dir_id/inner_path
172*/
173#[derive(Clone)]
174pub struct NDNGetDataInputRequest {
175    pub common: NDNInputRequestCommon,
176
177    // 目前只支持ChunkId/FileId/DirId
178    pub object_id: ObjectId,
179
180    pub data_type: NDNDataType,
181
182    // request data range
183    pub range: Option<NDNDataRequestRange>,
184
185    // 对dir/objectmap有效
186    pub inner_path: Option<String>,
187
188    // get data from context instead of common.target
189    pub context: Option<String>,
190
191    // get data task's group
192    pub group: Option<String>,
193}
194
195impl fmt::Display for NDNGetDataInputRequest {
196    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
197        write!(f, "common: {}", self.common)?;
198        write!(f, ", object_id: {}", self.object_id)?;
199        write!(f, ", data_type: {}", self.data_type)?;
200
201        if let Some(range) = &self.range {
202            write!(f, ", range: {}", range.to_display_string())?;
203        }
204
205        write!(f, ", inner_path: {:?}", self.inner_path)?;
206
207        if let Some(context) = &self.context {
208            write!(f, ", context: {}", context)?;
209        }
210
211        if let Some(group) = &self.group {
212            write!(f, ", group: {}", group)?;
213        }
214
215        Ok(())
216    }
217}
218
219impl NDNGetDataInputRequest {
220    pub fn check_valid(&self) -> BuckyResult<()> {
221        self.common.check_param_with_referer(&self.object_id)
222    }
223}
224
225pub struct NDNGetDataInputResponse {
226    // chunk_id/file_id
227    pub object_id: ObjectId,
228
229    // file's owner
230    pub owner_id: Option<ObjectId>,
231
232    // 所属file的attr
233    pub attr: Option<Attributes>,
234
235    // resp ranges
236    pub range: Option<NDNDataResponseRange>,
237
238    // task group
239    pub group: Option<String>,
240
241    pub length: u64,
242    pub data: Box<dyn Read + Unpin + Send + Sync + 'static>,
243}
244
245impl fmt::Display for NDNGetDataInputResponse {
246    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
247        write!(f, "object_id: {}", self.object_id)?;
248
249        if let Some(owner) = &self.owner_id {
250            write!(f, ", owner: {}", owner)?;
251        }
252
253        if let Some(attr) = &self.attr {
254            write!(f, ", attr: {:?}", attr)?;
255        }
256
257        if let Some(range) = &self.range {
258            write!(f, ", range: {:?}", range)?;
259        }
260
261        if let Some(group) = &self.group {
262            write!(f, ", group: {:?}", group)?;
263        }
264        
265        write!(f, ", length: {}", self.length)
266    }
267}
268
269// put_data,目前支持chunk
270pub struct NDNPutDataInputRequest {
271    pub common: NDNInputRequestCommon,
272
273    pub object_id: ObjectId,
274    pub data_type: NDNDataType,
275    pub length: u64,
276    pub data: Box<dyn Read + Unpin + Send + Sync + 'static>,
277}
278
279impl fmt::Display for NDNPutDataInputRequest {
280    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
281        write!(f, "common: {}", self.common)?;
282        write!(f, ", object_id: {}", self.object_id)?;
283
284        write!(f, ", length: {}", self.length)
285    }
286}
287
288impl NDNPutDataInputRequest {
289    pub fn clone_without_data(&self) -> Self {
290        Self {
291            common: self.common.clone(),
292            object_id: self.object_id.clone(),
293            data_type: NDNDataType::Mem,
294            length: self.length,
295            data: Box::new(async_std::io::Cursor::new(vec![])),
296        }
297    }
298}
299
300pub struct NDNPutDataInputResponse {
301    pub result: NDNPutDataResult,
302}
303
304impl fmt::Display for NDNPutDataInputResponse {
305    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
306        write!(f, "result: {:?}", self.result)
307    }
308}
309
310#[derive(Clone)]
311pub struct NDNDeleteDataInputRequest {
312    pub common: NDNInputRequestCommon,
313
314    pub object_id: ObjectId,
315
316    // 对dir_id有效
317    pub inner_path: Option<String>,
318}
319
320impl fmt::Display for NDNDeleteDataInputRequest {
321    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
322        write!(f, "common: {}", self.common)?;
323        write!(f, ", object_id: {}", self.object_id)?;
324
325        write!(f, ", inner_path: {:?}", self.inner_path)
326    }
327}
328
329pub struct NDNDeleteDataInputResponse {
330    pub object_id: ObjectId,
331}
332
333impl fmt::Display for NDNDeleteDataInputResponse {
334    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
335        write!(f, "object_id: {:?}", self.object_id)
336    }
337}
338
339// query flags for the return value optional fields
340pub const NDN_QUERY_FILE_REQUEST_FLAG_QUICK_HASN: u32 =
341    cyfs_util::cache::NDC_FILE_REQUEST_FLAG_QUICK_HASN;
342pub const NDN_QUERY_FILE_REQUEST_FLAG_REF_DIRS: u32 =
343    cyfs_util::cache::NDC_FILE_REQUEST_FLAG_REF_DIRS;
344
345#[derive(Debug, Clone)]
346pub enum NDNQueryFileParam {
347    File(ObjectId),
348    Hash(HashValue),
349    QuickHash(String),
350    Chunk(ChunkId),
351}
352
353impl NDNQueryFileParam {
354    pub fn as_str(&self) -> &str {
355        match self {
356            Self::File(_) => "file",
357            Self::Hash(_) => "hash",
358            Self::QuickHash(_) => "quick-hash",
359            Self::Chunk(_) => "chunk",
360        }
361    }
362
363    pub fn file_id(&self) -> Option<ObjectId> {
364        match self {
365            Self::File(id) => Some(id.to_owned()),
366            _ => None,
367        }
368    }
369
370    pub fn to_key_pair(&self) -> (&str, String) {
371        let value = match self {
372            Self::File(id) => id.to_string(),
373            Self::Hash(hash) => hash.to_hex_string(),
374            Self::QuickHash(hash) => hash.clone(),
375            Self::Chunk(id) => id.to_string(),
376        };
377
378        (self.as_str(), value)
379    }
380
381    pub fn from_key_pair(t: &str, value: &str) -> BuckyResult<Self> {
382        let ret = match t {
383            "file" => {
384                let value = ObjectId::from_str(value)?;
385                Self::File(value)
386            }
387            "hash" => {
388                let value = HashValue::from_str(value)?;
389                Self::Hash(value)
390            }
391            "quick-hash" => Self::QuickHash(value.to_owned()),
392            "chunk" => {
393                let value = ChunkId::from_str(value)?;
394                Self::Chunk(value)
395            }
396            _ => {
397                let msg = format!("unknown NDNQueryFileParam: {}, {}", t, value);
398                error!("{}", msg);
399                return Err(BuckyError::new(BuckyErrorCode::InvalidParam, msg));
400            }
401        };
402
403        Ok(ret)
404    }
405}
406
407impl fmt::Display for NDNQueryFileParam {
408    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
409        let (t, v) = self.to_key_pair();
410        write!(f, "{}={}", t, v)
411    }
412}
413
414#[derive(Clone)]
415pub struct NDNQueryFileInputRequest {
416    pub common: NDNInputRequestCommon,
417
418    pub param: NDNQueryFileParam,
419}
420
421impl fmt::Display for NDNQueryFileInputRequest {
422    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
423        write!(f, "common: {}", self.common)?;
424        write!(f, ", param: {}", self.param)
425    }
426}
427
428pub struct NDNQueryFileInfo {
429    pub file_id: FileId,
430
431    pub hash: String,
432
433    pub length: u64,
434
435    pub flags: u32,
436
437    pub owner: Option<ObjectId>,
438
439    // 可选,关联的quickhash
440    pub quick_hash: Option<Vec<String>>,
441
442    // 可选,关联的dirs
443    pub ref_dirs: Option<Vec<FileDirRef>>,
444}
445
446impl fmt::Display for NDNQueryFileInfo {
447    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
448        write!(
449            f,
450            "file_id: {}, hash={}, length={}, flags={}",
451            self.file_id, self.hash, self.length, self.flags
452        )?;
453
454        if let Some(owner) = &self.owner {
455            write!(f, ", owner={}", owner)?;
456        }
457        if let Some(quick_hash) = &self.quick_hash {
458            write!(f, ", quick_hash={:?}", quick_hash)?;
459        }
460        if let Some(ref_dirs) = &self.ref_dirs {
461            write!(f, ", ref_dirs={:?}", ref_dirs)?;
462        }
463
464        Ok(())
465    }
466}
467
468pub struct NDNQueryFileInputResponse {
469    pub list: Vec<NDNQueryFileInfo>,
470}