vika_community 0.1.1

rust for vika api.
Documentation
use serde::{Deserialize, Serialize};
use serde_json::{json, Map, Value};

#[derive(Deserialize, Serialize, Debug)]
pub struct Record {
    #[serde(rename = "recordId")]
    pub record_id: String,

    pub fields: Value,

    #[serde(rename = "createdAt")]
    pub created_at: u64,

    #[serde(rename = "updatedAt")]
    pub updated_at: u64,
}

#[derive(Deserialize, Serialize, Debug)]
pub struct GetRecordsResp {
    #[serde(rename = "pageNum")]
    pub page_num: u32,

    pub records: Vec<Record>,

    #[serde(rename = "pageSize")]
    pub page_size: u32,

    pub total: u32,
}

#[derive(Deserialize, Serialize)]
pub struct GetRecordsReq {
    field: Map<String, Value>,
}

impl GetRecordsReq {
    pub fn builder() -> GetRecordsReqBuilder {
        GetRecordsReqBuilder { field: Map::new() }
    }

    pub fn to_parameter_vec(self) -> Vec<(String, String)> {
        let mut result: Vec<(String, String)> = Vec::new();
        for (key, value) in self.field {
            if key.eq("recordIds") {
                let record_ids = value.as_array().unwrap();
                for record_id in record_ids {
                    result.push((key.clone(), record_id.as_str().unwrap().to_string()))
                }
            } else if key.eq("fields") {
                let fields = value.as_array().unwrap();
                for field in fields {
                    result.push((
                        String::from("fields[]"),
                        field.as_str().unwrap().to_string(),
                    ))
                }
            } else if key.eq("sort") {
                let sorts = value.as_array().unwrap();
                for sort in sorts {
                    result.push((
                        format!("sort[][field]",),
                        sort[0].as_str().unwrap().to_string(),
                    ));
                    result.push((
                        format!("sort[][order]",),
                        sort[1].as_str().unwrap().to_string(),
                    ));
                }
            } else if key.eq("pageSize") || key.eq("maxRecords") || key.eq("pageNum") {
                result.push((key, value.as_u64().unwrap().to_string()));
            } else {
                result.push((key, String::from(value.as_str().unwrap())));
            }
        }
        result
    }
}

pub struct GetRecordsReqBuilder {
    field: Map<String, Value>,
}

impl GetRecordsReqBuilder {
    pub fn page_size(mut self, page_size: u64) -> GetRecordsReqBuilder {
        self.field
            .insert(String::from("pageSize"), json!(page_size));
        self
    }

    pub fn max_records(mut self, max_records: u64) -> GetRecordsReqBuilder {
        self.field
            .insert(String::from("maxRecords"), json!(max_records));
        self
    }

    pub fn page_num(mut self, page_num: u64) -> GetRecordsReqBuilder {
        self.field.insert(String::from("pageNum"), json!(page_num));
        self
    }

    pub fn sort(mut self, sort: Vec<Sort>) -> GetRecordsReqBuilder {
        self.field.insert(String::from("sort"), json!(sort));
        self
    }

    pub fn record_ids(mut self, record_ids: Vec<String>) -> GetRecordsReqBuilder {
        self.field
            .insert(String::from("recordIds"), json!(record_ids));
        self
    }

    pub fn view_id(mut self, view_id: String) -> GetRecordsReqBuilder {
        self.field.insert(String::from("viewId"), json!(view_id));
        self
    }

    pub fn fields(mut self, fields: Vec<String>) -> GetRecordsReqBuilder {
        self.field.insert(String::from("fields"), json!(fields));
        self
    }

    pub fn filter_by_formula(mut self, filter_by_formula: String) -> GetRecordsReqBuilder {
        self.field
            .insert(String::from("filterByFormula"), json!(filter_by_formula));
        self
    }

    pub fn cell_format(mut self, cell_format: String) -> GetRecordsReqBuilder {
        self.field
            .insert(String::from("cellFormat"), json!(cell_format));
        self
    }

    pub fn field_key(mut self, field_key: String) -> GetRecordsReqBuilder {
        self.field
            .insert(String::from("fieldKey"), json!(field_key));
        self
    }

    pub fn build(self) -> GetRecordsReq {
        GetRecordsReq { field: self.field }
    }
}

#[derive(Deserialize, Serialize)]
pub struct Sort(pub String, pub String);

pub type PatchRecordsReq = PostRecordsReq;

#[derive(Deserialize, Serialize, Debug)]
pub struct PostRecordsReq {
    #[serde(rename = "fieldKey")]
    pub field_key: String,

    pub records: Vec<RecordMap>,
}

impl PostRecordsReq {
    pub fn to_json_string(self) -> String {
        let mut value: Map<String, Value> = Map::new();
        value.insert("fieldKey".to_string(), Value::String(self.field_key));
        let mut record_values: Vec<Value> = Vec::new();
        for record in self.records {
            let record_value_string = serde_json::to_string(&record).unwrap();
            let record_value: Value = serde_json::from_str(&record_value_string).unwrap();
            record_values.push(record_value);
        }
        value.insert("records".to_string(), Value::Array(record_values));
        serde_json::to_string(&value).unwrap()
    }
}

#[derive(Deserialize, Serialize, Debug)]
pub struct RecordMap {
    #[serde(rename = "recordId")]
    record_id: String,

    fields: Map<String, Value>,
}

impl RecordMap {
    pub fn builder() -> RecordMapBuilder {
        RecordMapBuilder {
            record_id: "".to_string(),
            fields: Map::new(),
        }
    }
}

pub struct RecordMapBuilder {
    pub record_id: String,

    pub fields: Map<String, Value>,
}

impl RecordMapBuilder {
    pub fn record_id(mut self, record_id: String) -> RecordMapBuilder {
        self.record_id = record_id;
        self
    }

    pub fn put_string(mut self, field_key: String, field_value: String) -> RecordMapBuilder {
        self.fields.insert(field_key, Value::String(field_value));
        self
    }

    pub fn put_strings(mut self, field_key: String, field_values: Vec<String>) -> RecordMapBuilder {
        let mut values: Vec<Value> = Vec::new();
        for field_value in field_values {
            values.push(Value::String(field_value));
        }
        self.fields.insert(field_key, Value::Array(values));
        self
    }

    pub fn build(self) -> RecordMap {
        RecordMap {
            record_id: self.record_id,
            fields: self.fields,
        }
    }
}

pub type PatchRecordsResp = PostRecordsResp;

#[derive(Deserialize, Serialize, Debug)]
pub struct PostRecordsResp {
    pub records: Vec<Record>,
}

#[cfg(test)]
mod tests {

    use super::*;

    #[test]
    fn get_records_req() {
        let get_records_req = GetRecordsReq::builder()
            .page_size(1)
            .max_records(1)
            .page_num(1)
            .sort(vec![
                Sort("1".to_string(), "asc".to_string()),
                Sort("2".to_string(), "desc".to_string()),
            ])
            .record_ids(vec!["1".to_string(), "2".to_string()])
            .view_id("1".to_string())
            .fields(vec!["1".to_string(), "2".to_string()])
            .filter_by_formula("1".to_string())
            .cell_format("1".to_string())
            .field_key("1".to_string())
            .build();
        println!("{:?}", get_records_req.to_parameter_vec())
    }

    #[test]
    fn post_records_req() {
        let record1 = RecordMap::builder()
            .put_string("field_key1".to_string(), "field_value1".to_string())
            .put_string("field_key2".to_string(), "field_value2".to_string())
            .build();
        let record2 = RecordMap::builder()
            .put_string("field_key1".to_string(), "field_value1".to_string())
            .put_string("field_key2".to_string(), "field_value2".to_string())
            .build();
        let req = PostRecordsReq {
            field_key: "name".to_string(),
            records: vec![record1, record2],
        };

        assert_eq!(
            r#"{"fieldKey":"name","records":[{"fields":{"field_key1":"field_value1","field_key2":"field_value2"},"recordId":""},{"fields":{"field_key1":"field_value1","field_key2":"field_value2"},"recordId":""}]}"#,
            req.to_json_string()
        )
    }

    #[test]
    fn patch_records_req() {
        let record1 = RecordMap::builder()
            .record_id("rec1".to_string())
            .put_string("field_key1".to_string(), "field_value1".to_string())
            .put_string("field_key2".to_string(), "field_value2".to_string())
            .build();
        let record2 = RecordMap::builder()
            .record_id("rec1".to_string())
            .put_string("field_key1".to_string(), "field_value1".to_string())
            .put_string("field_key2".to_string(), "field_value2".to_string())
            .build();
        let req = PostRecordsReq {
            field_key: "name".to_string(),
            records: vec![record1, record2],
        };
        assert_eq!(
            r#"{"fieldKey":"name","records":[{"fields":{"field_key1":"field_value1","field_key2":"field_value2"},"recordId":"rec1"},{"fields":{"field_key1":"field_value1","field_key2":"field_value2"},"recordId":"rec1"}]}"#,
            req.to_json_string()
        )
    }
}