1use crate::*;
2use cyfs_base::*;
3
4use http_types::{Method, Request, Response, StatusCode, Url};
5use serde_json::{Map, Value};
6use std::fmt;
7use std::str::FromStr;
8
9#[derive(Debug, Clone)]
10pub struct SelectTimeRange {
11 pub begin: Option<u64>,
13 pub end: Option<u64>,
14}
15
16#[derive(Debug, Clone)]
17pub struct SelectFilter {
18 pub obj_type: Option<u16>,
19 pub obj_type_code: Option<ObjectTypeCode>,
20
21 pub dec_id: Option<ObjectId>,
22 pub owner_id: Option<ObjectId>,
23 pub author_id: Option<ObjectId>,
24
25 pub create_time: Option<SelectTimeRange>,
26 pub update_time: Option<SelectTimeRange>,
27 pub insert_time: Option<SelectTimeRange>,
28
29 pub flags: Option<u32>,
31}
32
33impl Default for SelectFilter {
34 fn default() -> Self {
35 Self {
36 obj_type: None,
37 obj_type_code: None,
38
39 dec_id: None,
40 owner_id: None,
41 author_id: None,
42
43 create_time: None,
44 update_time: None,
45 insert_time: None,
46
47 flags: None,
48 }
49 }
50}
51
52impl fmt::Display for SelectFilter {
53 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54 if let Some(v) = &self.obj_type {
55 write!(f, "obj_type:{} ", v)?;
56 }
57 if let Some(v) = &self.obj_type_code {
58 write!(f, "obj_type_code:{} ", v.to_u16())?;
59 }
60
61 if let Some(v) = &self.dec_id {
62 write!(f, "dec_id:{} ", v.to_string())?;
63 }
64 if let Some(v) = &self.owner_id {
65 write!(f, "owner_id:{} ", v.to_string())?;
66 }
67 if let Some(v) = &self.author_id {
68 write!(f, "author_id:{} ", v.to_string())?;
69 }
70
71 if let Some(v) = &self.create_time {
72 write!(f, "create_time:{:?} ", v)?;
73 }
74 if let Some(v) = &self.update_time {
75 write!(f, "update_time:{:?} ", v)?;
76 }
77 if let Some(v) = &self.insert_time {
78 write!(f, "insert_time:{:?} ", v)?;
79 }
80
81 if let Some(v) = &self.flags {
82 write!(f, "flags:{} ", v)?;
83 }
84 Ok(())
85 }
86}
87
88#[derive(Debug, Clone)]
89pub struct SelectOption {
90 pub page_size: u16,
92
93 pub page_index: u16,
95}
96
97impl Default for SelectOption {
98 fn default() -> Self {
99 Self {
100 page_size: 32_u16,
101 page_index: 0_u16,
102 }
103 }
104}
105
106impl fmt::Display for SelectOption {
107 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
108 write!(f, "page_size:{} ", self.page_size)?;
109 write!(f, "page_index:{}", self.page_index)
110 }
111}
112
113
114#[derive(Debug, Clone, RawDecode, RawEncode)]
115pub struct SelectResponseObjectMetaInfo {
116 pub insert_time: u64,
117 pub create_dec_id: Option<ObjectId>,
118 pub context: Option<String>,
119 pub last_access_rpath: Option<String>,
120 pub access_string: Option<u32>,
121}
122
123#[derive(Debug, Clone, RawEncode, RawDecode)]
124pub struct SelectResponseObjectInfo {
125 pub meta: SelectResponseObjectMetaInfo,
126 pub object: Option<NONObjectInfo>,
127}
128
129impl SelectResponseObjectInfo {
130 fn from_meta(meta: SelectResponseObjectMetaInfo) -> Self {
131 Self {
132 meta,
133 object: None,
134 }
135 }
136
137 fn meta(&self) -> &SelectResponseObjectMetaInfo {
138 &self.meta
139 }
140}
141
142impl fmt::Display for SelectResponseObjectMetaInfo {
143 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
144 write!(f, "insert_time:{}", self.insert_time)?;
145
146 if let Some(v) = &self.create_dec_id {
147 write!(f, ", create_dec_id:{} ", v)?;
148 }
149 if let Some(v) = &self.context {
150 write!(f, ", context:{} ", v)?;
151 }
152 if let Some(v) = &self.last_access_rpath {
153 write!(f, ", last_access_rpath:{} ", v)?;
154 }
155 write!(f, ", access:{:?}", self.access_string)?;
156
157 Ok(())
158 }
159}
160
161impl fmt::Display for SelectResponseObjectInfo {
162 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
163 write!(f, "{} ", self.meta)?;
164
165 if let Some(obj) = &self.object {
166 write!(f, "object:{} ", obj)?;
167 }
168
169 Ok(())
170 }
171}
172
173impl JsonCodec<SelectResponseObjectMetaInfo> for SelectResponseObjectMetaInfo {
174 fn encode_json(&self) -> Map<String, Value> {
175 let mut obj = Map::new();
176
177 obj.insert(
178 "insert_time".to_owned(),
179 Value::String(self.insert_time.to_string()),
180 );
181
182 JsonCodecHelper::encode_option_string_field(&mut obj, "create_dec_id", self.create_dec_id.as_ref());
183 JsonCodecHelper::encode_option_string_field(&mut obj, "context", self.context.as_ref());
184 JsonCodecHelper::encode_option_string_field(&mut obj, "last_access_rpath", self.last_access_rpath.as_ref());
185 JsonCodecHelper::encode_option_number_field(&mut obj, "access", self.access_string);
186
187 obj
188 }
189
190 fn decode_json(obj: &Map<String, Value>) -> BuckyResult<Self> {
191 Ok(Self {
192 insert_time: JsonCodecHelper::decode_int_field(obj, "insert_time")?,
193 create_dec_id: JsonCodecHelper::decode_option_string_field(obj, "create_dec_id")?,
194 context: JsonCodecHelper::decode_option_string_field(obj, "context")?,
195 last_access_rpath: JsonCodecHelper::decode_option_string_field(obj, "last_access_rpath")?,
196 access_string: JsonCodecHelper::decode_option_int_field(obj, "access")?,
197 })
198 }
199}
200
201impl JsonCodec<SelectResponseObjectInfo> for SelectResponseObjectInfo {
202 fn encode_json(&self) -> Map<String, Value> {
203 let mut obj = Map::new();
204
205 JsonCodecHelper::encode_field(&mut obj, "meta", &self.meta);
206 let mut obj = self.meta().encode_json();
207 if let Some(object) = &self.object {
208 JsonCodecHelper::encode_field(&mut obj, "object", object);
209 }
210 obj
211 }
212
213 fn decode_json(obj: &Map<String, Value>) -> BuckyResult<Self> {
214 Ok(Self {
215 meta: JsonCodecHelper::decode_field(obj, "meta")?,
216 object: JsonCodecHelper::decode_option_field(obj, "object")?,
217 })
218 }
219}
220
221impl SelectResponseObjectInfo {
222 pub fn bind_object(&mut self, buf: Vec<u8>) -> BuckyResult<()> {
224 assert!(self.object.is_none());
225
226 let info = NONObjectInfo::new_from_object_raw(buf)?;
227 self.object = Some(info);
228
229 Ok(())
230 }
231}
232
233impl Default for SelectTimeRange {
234 fn default() -> Self {
235 Self {
236 begin: None,
237 end: None,
238 }
239 }
240}
241
242impl SelectTimeRange {
243 pub fn is_empty(&self) -> bool {
244 self.begin.is_none() && self.end.is_none()
245 }
246}
247
248impl ToString for SelectTimeRange {
249 fn to_string(&self) -> String {
250 if self.begin.is_some() && self.end.is_some() {
251 format!(
252 "{}:{}",
253 self.begin.as_ref().unwrap(),
254 self.end.as_ref().unwrap()
255 )
256 } else if self.begin.is_some() {
257 format!("{}:", self.begin.as_ref().unwrap())
258 } else if self.end.is_some() {
259 format!(":{}", self.end.as_ref().unwrap())
260 } else {
261 ":".to_owned()
262 }
263 }
264}
265
266impl FromStr for SelectTimeRange {
267 type Err = BuckyError;
268 fn from_str(s: &str) -> Result<Self, Self::Err> {
269 let parts: Vec<&str> = s.split(":").collect();
270 if parts.len() != 2 {
271 return Err(BuckyError::from(BuckyErrorCode::InvalidFormat));
272 }
273
274 let mut ret = Self {
275 begin: None,
276 end: None,
277 };
278
279 let begin = parts[0].trim();
280 if !begin.is_empty() {
281 let begin: u64 = begin.parse().map_err(|e| {
282 error!("decode time error: {} {}", begin, e);
283 BuckyError::from(BuckyErrorCode::InvalidFormat)
284 })?;
285
286 ret.begin = Some(begin);
287 }
288
289 let end = parts[1].trim();
290 if !end.is_empty() {
291 let end: u64 = end.parse().map_err(|e| {
292 error!("decode time error: {} {}", end, e);
293 BuckyError::from(BuckyErrorCode::InvalidFormat)
294 })?;
295
296 ret.end = Some(end);
297 }
298
299 Ok(ret)
300 }
301}
302
303pub struct SelectResponse {
304 pub objects: Vec<SelectResponseObjectInfo>,
305}
306
307impl fmt::Display for SelectResponse {
308 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
309 write!(f, "size:{}", self.objects.len())?;
310 for item in &self.objects {
311 write!(f, ",{}", item)?;
312 }
313
314 Ok(())
315 }
316}
317
318impl SelectResponse {
319 pub fn encode_objects(http_resp: &mut Response, objects: Vec<SelectResponseObjectInfo>) -> BuckyResult<()> {
320 if objects.is_empty() {
321 return Ok(());
322 }
323
324 let buf = objects.to_vec()?;
325
326 debug!(
327 "will send select all_buf: len={}, count={}",
328 buf.len(),
329 objects.len(),
330 );
332
333 http_resp.set_body(buf);
334
335 Ok(())
336 }
337
338 pub fn into_resonse(self) -> BuckyResult<Response> {
339 let mut resp = RequestorHelper::new_response(StatusCode::Ok);
340 if !self.objects.is_empty() {
341 Self::encode_objects(&mut resp, self.objects)?;
342 }
343
344 Ok(resp)
345 }
346
347 pub async fn from_respone(mut resp: Response) -> BuckyResult<Self> {
348 let all_buf = resp.body_bytes().await.map_err(|e| {
349 let msg = format!("read select resp body bytes error: {}", e);
350 error!("{}", msg);
351
352 BuckyError::new(BuckyErrorCode::IoError, msg)
353 })?;
354
355 let objects = if all_buf.len() > 0 {
356 let (objects, _) = Vec::raw_decode(&all_buf)?;
357 objects
358 } else {
359 vec![]
360 };
361
362 debug!(
363 "recv select all_buf: len={}, count={}",
364 all_buf.len(),
365 objects.len(),
366 );
367
368 Ok(Self { objects })
369 }
370}
371
372pub struct SelectFilterUrlCodec;
373impl SelectFilterUrlCodec {
374 pub fn encode(url: &mut Url, filter: &SelectFilter) {
375 let mut query = url.query_pairs_mut();
376 if let Some(obj_type) = &filter.obj_type {
377 query.append_pair("obj-type", &obj_type.to_string());
378 }
379 if let Some(obj_type_code) = &filter.obj_type_code {
380 query.append_pair("obj-type-code", &obj_type_code.to_string());
381 }
382
383 if let Some(dec_id) = &filter.dec_id {
384 query.append_pair("dec-id", &dec_id.to_string());
385 }
386 if let Some(owner_id) = &filter.owner_id {
387 query.append_pair("owner-id", &owner_id.to_string());
388 }
389 if let Some(author_id) = &filter.author_id {
390 query.append_pair("author-id", &author_id.to_string());
391 }
392
393 if let Some(create_time) = &filter.create_time {
394 query.append_pair("create-time", &create_time.to_string());
395 }
396 if let Some(update_time) = &filter.update_time {
397 query.append_pair("update-time", &update_time.to_string());
398 }
399 if let Some(insert_time) = &filter.insert_time {
400 query.append_pair("insert-time", &insert_time.to_string());
401 }
402
403 if let Some(flags) = &filter.flags {
404 query.append_pair("flags", &flags.to_string());
405 }
406 }
407
408 pub fn decode(url: &Url) -> BuckyResult<SelectFilter> {
409 let mut obj_type = None;
410 let mut obj_type_code = None;
411
412 let mut dec_id = None;
413 let mut owner_id = None;
414 let mut author_id = None;
415
416 let mut create_time = None;
417 let mut update_time = None;
418 let mut insert_time = None;
419
420 let mut flags = None;
421
422 for (k, v) in url.query_pairs() {
423 match k.as_ref() {
424 "obj-type" => {
425 obj_type = Some(RequestorHelper::decode_url_param(k, v)?);
426 }
427 "obj-type-code" => {
428 obj_type_code = Some(RequestorHelper::decode_url_param(k, v)?);
429 }
430
431 "dec-id" => {
432 dec_id = Some(RequestorHelper::decode_url_param(k, v)?);
433 }
434 "owner-id" => {
435 owner_id = Some(RequestorHelper::decode_url_param(k, v)?);
436 }
437 "author-id" => {
438 author_id = Some(RequestorHelper::decode_url_param(k, v)?);
439 }
440
441 "create-time" => {
442 create_time = Some(RequestorHelper::decode_url_param(k, v)?);
443 }
444 "update-time" => {
445 update_time = Some(RequestorHelper::decode_url_param(k, v)?);
446 }
447 "insert-time" => {
448 insert_time = Some(RequestorHelper::decode_url_param(k, v)?);
449 }
450
451 "flags" => {
452 flags = Some(RequestorHelper::decode_url_param(k, v)?);
453 }
454
455 _ => {
456 warn!("unknown select filter param: {} = {}", k, v);
457 }
458 }
459 }
460
461 let ret = SelectFilter {
462 obj_type,
463 obj_type_code,
464
465 dec_id,
466 owner_id,
467 author_id,
468
469 create_time,
470 insert_time,
471 update_time,
472
473 flags,
474 };
475
476 Ok(ret)
477 }
478}
479
480pub struct SelectOptionCodec;
481
482impl SelectOptionCodec {
483 pub fn encode(req: &mut Request, opt: &Option<SelectOption>) {
484 if let Some(opt) = opt {
485 RequestorHelper::encode_header(req, cyfs_base::CYFS_PAGE_SIZE, &opt.page_size);
486 RequestorHelper::encode_header(req, cyfs_base::CYFS_PAGE_INDEX, &opt.page_index);
487 }
488 }
489
490 pub fn decode(req: &Request) -> BuckyResult<Option<SelectOption>> {
491 let page_size: Option<u16> =
492 RequestorHelper::decode_optional_header(req, cyfs_base::CYFS_PAGE_SIZE)?;
493 let page_index: Option<u16> =
494 RequestorHelper::decode_optional_header(req, cyfs_base::CYFS_PAGE_INDEX)?;
495
496 let ret = if page_size.is_some() || page_index.is_some() {
497 let mut select_opt = SelectOption::default();
498 if page_size.is_some() {
499 select_opt.page_size = page_size.unwrap();
500 }
501 if page_index.is_some() {
502 select_opt.page_index = page_index.unwrap();
503 }
504 Some(select_opt)
505 } else {
506 None
507 };
508 Ok(ret)
509 }
510}
511
512pub struct SelectEncoder {
513 service_url: Url,
514}
515
516impl SelectEncoder {
517 pub fn new(service_url: Url) -> Self {
518 Self { service_url }
519 }
520
521 pub fn encode_select_request(&self, req: &SelectFilter, opt: Option<&SelectOption>) -> Request {
522 let mut http_req = Request::new(Method::Get, self.service_url.clone());
523
524 http_req.append_header("Access-Control-Allow-Headers", cyfs_base::CYFS_OBJECTS);
527 http_req.append_header("Access-Control-Expose-Headers", cyfs_base::CYFS_OBJECTS);
528
529 RequestorHelper::encode_opt_header(&mut http_req, cyfs_base::CYFS_OBJ_TYPE, &req.obj_type);
530 RequestorHelper::encode_opt_header(
531 &mut http_req,
532 cyfs_base::CYFS_OBJ_TYPE_CODE,
533 &req.obj_type_code,
534 );
535
536 RequestorHelper::encode_opt_header(
537 &mut http_req,
538 cyfs_base::CYFS_FILTER_DEC_ID,
539 &req.dec_id,
540 );
541 RequestorHelper::encode_opt_header(&mut http_req, cyfs_base::CYFS_OWNER_ID, &req.owner_id);
542 RequestorHelper::encode_opt_header(
543 &mut http_req,
544 cyfs_base::CYFS_AUTHOR_ID,
545 &req.author_id,
546 );
547
548 RequestorHelper::encode_opt_header(
549 &mut http_req,
550 cyfs_base::CYFS_CREATE_TIME,
551 &req.create_time,
552 );
553 RequestorHelper::encode_opt_header(
554 &mut http_req,
555 cyfs_base::CYFS_UPDATE_TIME,
556 &req.update_time,
557 );
558 RequestorHelper::encode_opt_header(
559 &mut http_req,
560 cyfs_base::CYFS_INSERT_TIME,
561 &req.insert_time,
562 );
563
564 RequestorHelper::encode_opt_header(&mut http_req, cyfs_base::CYFS_FILTER_FLAGS, &req.flags);
565
566 if opt.is_some() {
567 let opt = opt.unwrap();
568
569 RequestorHelper::encode_header(
570 &mut http_req,
571 cyfs_base::CYFS_PAGE_SIZE,
572 &opt.page_size,
573 );
574 RequestorHelper::encode_header(
575 &mut http_req,
576 cyfs_base::CYFS_PAGE_INDEX,
577 &opt.page_index,
578 );
579 }
580
581 http_req
582 }
583}
584
585pub struct SelectDecoder;
586
587impl SelectDecoder {
588 pub fn decode_select_request(req: &Request) -> BuckyResult<(SelectFilter, SelectOption)> {
589 let obj_type: Option<u16> =
591 RequestorHelper::decode_optional_header(req, cyfs_base::CYFS_OBJ_TYPE)?;
592 let obj_type_code: Option<ObjectTypeCode> =
593 RequestorHelper::decode_optional_header(req, cyfs_base::CYFS_OBJ_TYPE_CODE)?;
594
595 let dec_id: Option<ObjectId> =
596 RequestorHelper::decode_optional_header(req, cyfs_base::CYFS_FILTER_DEC_ID)?;
597 let owner_id: Option<ObjectId> =
598 RequestorHelper::decode_optional_header(req, cyfs_base::CYFS_OWNER_ID)?;
599 let author_id: Option<ObjectId> =
600 RequestorHelper::decode_optional_header(req, cyfs_base::CYFS_AUTHOR_ID)?;
601
602 let create_time: Option<SelectTimeRange> =
603 RequestorHelper::decode_optional_header(req, cyfs_base::CYFS_CREATE_TIME)?;
604 let update_time: Option<SelectTimeRange> =
605 RequestorHelper::decode_optional_header(req, cyfs_base::CYFS_UPDATE_TIME)?;
606 let insert_time: Option<SelectTimeRange> =
607 RequestorHelper::decode_optional_header(req, cyfs_base::CYFS_INSERT_TIME)?;
608
609 let flags: Option<u32> =
610 RequestorHelper::decode_optional_header(req, cyfs_base::CYFS_FILTER_FLAGS)?;
611
612 let page_size: Option<u16> =
614 RequestorHelper::decode_optional_header(req, cyfs_base::CYFS_PAGE_SIZE)?;
615 let page_index: Option<u16> =
616 RequestorHelper::decode_optional_header(req, cyfs_base::CYFS_PAGE_INDEX)?;
617
618 let select_req = SelectFilter {
619 obj_type,
620 obj_type_code,
621
622 dec_id,
623 owner_id,
624 author_id,
625
626 create_time,
627 update_time,
628 insert_time,
629
630 flags,
631 };
632
633 let mut select_opt = SelectOption::default();
634 if page_size.is_some() {
635 select_opt.page_size = page_size.unwrap();
636 }
637 if page_index.is_some() {
638 select_opt.page_index = page_index.unwrap();
639 }
640
641 Ok((select_req, select_opt))
642 }
643}
644
645impl JsonCodec<SelectTimeRange> for SelectTimeRange {
646 fn encode_json(&self) -> Map<String, Value> {
647 let mut obj = Map::new();
648
649 JsonCodecHelper::encode_option_number_field(&mut obj, "begin", self.begin);
650 JsonCodecHelper::encode_option_number_field(&mut obj, "end", self.end);
651
652 obj
653 }
654
655 fn decode_json(obj: &Map<String, Value>) -> BuckyResult<SelectTimeRange> {
656 Ok(Self {
657 begin: JsonCodecHelper::decode_option_int_field(obj, "begin")?,
658 end: JsonCodecHelper::decode_option_int_field(obj, "end")?,
659 })
660 }
661}
662
663impl JsonCodec<SelectFilter> for SelectFilter {
664 fn encode_json(&self) -> Map<String, Value> {
665 let mut obj = Map::new();
666
667 JsonCodecHelper::encode_option_number_field(&mut obj, "obj_type", self.obj_type);
668 JsonCodecHelper::encode_option_number_field(
669 &mut obj,
670 "obj_type_code",
671 self.obj_type_code.as_ref().map(|v| v.to_u16()),
672 );
673
674 JsonCodecHelper::encode_option_string_field(&mut obj, "dec_id", self.dec_id.as_ref());
675 JsonCodecHelper::encode_option_string_field(&mut obj, "owner_id", self.owner_id.as_ref());
676 JsonCodecHelper::encode_option_string_field(&mut obj, "author_id", self.author_id.as_ref());
677
678 JsonCodecHelper::encode_option_field(&mut obj, "create_time", self.create_time.as_ref());
679 JsonCodecHelper::encode_option_field(&mut obj, "update_time", self.update_time.as_ref());
680 JsonCodecHelper::encode_option_field(&mut obj, "insert_time", self.insert_time.as_ref());
681
682 JsonCodecHelper::encode_option_number_field(&mut obj, "flags", self.flags);
683
684 obj
685 }
686
687 fn decode_json(obj: &Map<String, Value>) -> BuckyResult<SelectFilter> {
688 let obj_type_code: Option<u16> =
689 JsonCodecHelper::decode_option_int_field(obj, "obj_type_code")?;
690 Ok(Self {
691 obj_type: JsonCodecHelper::decode_option_int_field(obj, "obj_type")?,
692 obj_type_code: obj_type_code.map(|v| v.into()),
693
694 dec_id: JsonCodecHelper::decode_option_string_field(obj, "dec_id")?,
695 owner_id: JsonCodecHelper::decode_option_string_field(obj, "owner_id")?,
696 author_id: JsonCodecHelper::decode_option_string_field(obj, "author_id")?,
697
698 create_time: JsonCodecHelper::decode_option_field(obj, "create_time")?,
699 update_time: JsonCodecHelper::decode_option_field(obj, "update_time")?,
700 insert_time: JsonCodecHelper::decode_option_field(obj, "insert_time")?,
701
702 flags: JsonCodecHelper::decode_option_int_field(obj, "flags")?,
703 })
704 }
705}
706
707impl JsonCodec<SelectOption> for SelectOption {
708 fn encode_json(&self) -> Map<String, Value> {
709 let mut obj = Map::new();
710
711 JsonCodecHelper::encode_number_field(&mut obj, "page_index", self.page_index);
712 JsonCodecHelper::encode_number_field(&mut obj, "page_size", self.page_size);
713
714 obj
715 }
716
717 fn decode_json(obj: &Map<String, Value>) -> BuckyResult<SelectOption> {
718 Ok(Self {
719 page_index: JsonCodecHelper::decode_int_field(obj, "page_index")?,
720 page_size: JsonCodecHelper::decode_int_field(obj, "page_size")?,
721 })
722 }
723}