cyfs-lib 0.8.3

Rust cyfs-lib package
Documentation
use std::path::PathBuf;
use serde_json::{Map, Value};
use cyfs_base::*;
use cyfs_bdt::{
    TempSeq, 
    ChunkCodecDesc,
};
use super::{
    bdt_request::BdtDataRefererInfo
};

pub struct InterestHandlerRequest {
    pub session_id: TempSeq, 
    pub chunk: ChunkId,
    pub prefer_type: ChunkCodecDesc, 
    pub from: Option<DeviceId>,
    pub referer: Option<BdtDataRefererInfo>, 
    pub from_channel: DeviceId, 
    pub group_path: Option<String>
}


impl JsonCodec<InterestHandlerRequest> for InterestHandlerRequest {
    fn encode_json(&self) -> Map<String, Value> {
        let mut obj = Map::new();
        JsonCodecHelper::encode_number_field(&mut obj, "session_id", self.session_id.value());
        JsonCodecHelper::encode_string_field(&mut obj, "chunk", &self.chunk);
        JsonCodecHelper::encode_field(&mut obj, "prefer_type", &self.prefer_type);
        JsonCodecHelper::encode_option_string_field(&mut obj, "from", self.from.as_ref());
        JsonCodecHelper::encode_option_field(&mut obj, "referer", self.referer.as_ref());
        JsonCodecHelper::encode_string_field(&mut obj, "from_channel", &self.from_channel);
        JsonCodecHelper::encode_option_string_field(&mut obj, "group_path", self.group_path.as_ref());
        obj
    }

    fn decode_json(obj: &Map<String, Value>) -> BuckyResult<Self> {
        let session_id: u32 = JsonCodecHelper::decode_int_field(obj, "session_id")?;
        Ok(Self {
            session_id: TempSeq::from(session_id), 
            chunk: JsonCodecHelper::decode_string_field(obj, "chunk")?, 
            prefer_type: JsonCodecHelper::decode_field(obj, "prefer_type")?, 
            from: JsonCodecHelper::decode_option_string_field(obj, "from")?, 
            referer: JsonCodecHelper::decode_option_field(obj, "referer")?, 
            from_channel: JsonCodecHelper::decode_string_field(obj, "from_channel")?, 
            group_path: JsonCodecHelper::decode_option_string_field(obj, "group_path")?, 
        })
    }
}


impl std::fmt::Display for InterestHandlerRequest {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "session_id: {:?}", self.session_id)?;
        write!(f, ", chunk: {}", self.chunk)?;
        write!(f, ", prefer_type: {:?}", self.prefer_type)?;
        if let Some(from) = &self.from {
            write!(f, ", from: {}", from)?;
        }
        if let Some(referer) = &self.referer {
            write!(f, ", referer: {}", referer)?;
        }
        if let Some(group_path) = &self.group_path {
            write!(f, ", group_path: {}", group_path)?;
        }
        write!(f, ", from_channel: {:?}", self.from_channel)
       
    }
}


#[derive(Clone)]
pub struct RespInterestFields {
    pub err: BuckyErrorCode,
    pub redirect: Option<DeviceId>,
    pub redirect_referer_target: Option<ObjectId>,
}

impl std::fmt::Display for RespInterestFields {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "err: {}", self.err)?;
        if let Some(redierct) = &self.redirect {
            write!(f, ", redierct: {}", redierct)?;
        }
        if let Some(obj_id) = &self.redirect_referer_target {
            write!(f, ", redirect_referer_target: {}", obj_id)?;
        }
        Ok(())
    }
}


impl JsonCodec<RespInterestFields> for RespInterestFields {
    fn encode_json(&self) -> Map<String, Value> {
        let mut obj = Map::new();
        let err: u32 = self.err.into();
        JsonCodecHelper::encode_number_field(&mut obj, "err", err);
        JsonCodecHelper::encode_option_string_field(&mut obj, "redirect", self.redirect.as_ref());
        JsonCodecHelper::encode_option_string_field(&mut obj, "redirect_referer_target", self.redirect_referer_target.as_ref());
        obj
    }

    fn decode_json(obj: &Map<String, Value>) -> BuckyResult<Self> {
        let err: u32 = JsonCodecHelper::decode_int_field(obj, "err")?;
        Ok(Self {
            err: BuckyErrorCode::from(err), 
            redirect: JsonCodecHelper::decode_option_string_field(obj, "redirect")?, 
            redirect_referer_target: JsonCodecHelper::decode_option_string_field(obj, "decode_option_string_field")?, 
        })
    }
}

#[derive(Debug, Clone)]
pub enum InterestUploadSource {
    ChunkStore, 
    File {
        path: PathBuf, 
        offset: u64
    }
}

#[derive(Clone)]
pub enum InterestHandlerResponse {
    Default, 
    Upload {
        source: InterestUploadSource, 
        groups: Vec<String>
    }, 
    Transmit(DeviceId), 
    Resp(RespInterestFields), 
    Handled
}

impl InterestHandlerResponse {
    pub fn type_str(&self) -> &str {
        match self {
            Self::Default => "Default", 
            Self::Upload {..} => "Upload",
            Self::Transmit(_) => "Transmit",  
            Self::Resp(_) => "Resp", 
            Self::Handled => "Handled"
        }
    }

    pub fn resp_interest(&self) -> Option<&RespInterestFields> {
        if let Self::Resp(resp) = self {
            Some(resp)
        } else {
            None
        }
    }

    pub fn transmit_to(&self) -> Option<&DeviceId> {
        if let Self::Transmit(to) = self {
            Some(to)
        } else {
            None
        }
    }
}

impl JsonCodec<InterestHandlerResponse> for InterestHandlerResponse {
    fn encode_json(&self) -> Map<String, Value> {
        let mut obj = Map::new();
        match self {
            Self::Default => JsonCodecHelper::encode_string_field(&mut obj, "type", "Default"), 
            Self::Upload { source, groups }=> {
                JsonCodecHelper::encode_string_field(&mut obj, "type", "Upload");
                JsonCodecHelper::encode_str_array_field(&mut obj, "upload_groups", groups);
                match source {
                    InterestUploadSource::ChunkStore => {}, 
                    InterestUploadSource::File { path, offset } => {
                        JsonCodecHelper::encode_option_string_field(&mut obj, "upload_from_path", path.to_str());
                        JsonCodecHelper::encode_option_number_field(&mut obj, "upload_from_offset", Some(*offset));
                    }
                }
                
            }, 
            Self::Transmit(to) => {
                JsonCodecHelper::encode_string_field(&mut obj, "type", "Transmit");
                JsonCodecHelper::encode_option_string_field(&mut obj, "transmit_to", Some(to));
            }, 
            Self::Resp(resp) => {
                JsonCodecHelper::encode_string_field(&mut obj, "type", "Resp");
                JsonCodecHelper::encode_option_field(&mut obj, "resp", Some(resp));
            }, 
            Self::Handled => JsonCodecHelper::encode_string_field(&mut obj, "type", "Handled") 
        }
        obj
    }

    fn decode_json(obj: &Map<String, Value>) -> BuckyResult<Self> {
        let type_str: String = JsonCodecHelper::decode_string_field(obj, "type")?;
        match type_str.as_str() {
            "Default" => Ok(Self::Default), 
            "Upload" => {
                let groups = JsonCodecHelper::decode_str_array_field(obj, "upload_groups")?;
                let source = if let Some(path) = JsonCodecHelper::decode_option_string_field(obj, "upload_from_path")? {
                    let offset = JsonCodecHelper::decode_option_int_field(obj, "upload_from_offset")?.unwrap_or_default();
                    InterestUploadSource::File { path, offset }
                } else {
                    InterestUploadSource::ChunkStore
                };
                Ok(Self::Upload { source, groups })
            }, 
            "Transmit" => Ok(Self::Transmit(JsonCodecHelper::decode_option_string_field(obj, "transmit_to")?
                .ok_or_else(|| BuckyError::new(BuckyErrorCode::InvalidInput, "no transmit_to field"))?)), 
            "Resp" => Ok(Self::Resp(JsonCodecHelper::decode_option_field(obj, "resp")?
                .ok_or_else(|| BuckyError::new(BuckyErrorCode::InvalidInput, "no resp field"))?)), 
            "Handled" => Ok(Self::Handled), 
            _ => Err(BuckyError::new(BuckyErrorCode::InvalidInput, format!("invalid type {}", type_str)))
        }
    }
}


impl std::fmt::Display for InterestHandlerResponse {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        match self {
            Self::Default => write!(f, "Default")?, 
            Self::Upload { source, groups } => write!(f, "Upload{{groups:{:?},source:{:?}}}", groups, source)?, 
            Self::Transmit(to) => write!(f, "Transmit({})", to)?, 
            Self::Resp(resp) => write!(f, "Resp({})", resp)?, 
            Self::Handled => write!(f, "Handled")?
        }
        Ok(())
    }
}