vika 0.1.2

A Rust API for Vika.
Documentation
use serde::{Deserialize, Serialize};

use crate::{common::config::Config, common::http::ResponseSchema};

#[derive(Debug, Serialize, Deserialize)]
pub struct Node {
    pub id: String,
    pub name: String,
    pub icon: Option<String>,
    #[serde(rename = "type")]
    pub r#type: NodeType,
    #[serde(rename = "isFav")]
    pub is_fav: bool,
    ///API tokens are generated based on individual accounts. Users can retrieve a list of file nodes that they have specific permissions for using the API token..
    /// 0: Manager, able to add, delete views and records field, and allowed to edit fields, but nable to add and delete fields.
    /// 1: Editor, able to add, delete views and records field, and allowed to edit fields, but unable to add and delete fields.
    /// 2: Update-only, able to view, add and edit records, but unable to delete records.
    /// 3: Read-only, only allowed to view the data.
    pub permission: u8,
    #[serde(default)]
    pub children: Vec<Node>,
    pub parent_id: Option<String>,
}

#[derive(Debug, Serialize, Deserialize)]
pub enum NodeType {
    Datasheet,
    Mirror,
    Folder,
    Form,
    Dashboard,
    Automation,
}

impl std::fmt::Display for NodeType {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            NodeType::Datasheet => write!(f, "Datasheet"),
            NodeType::Mirror => write!(f, "Mirror"),
            NodeType::Folder => write!(f, "Folder"),
            NodeType::Form => write!(f, "Form"),
            NodeType::Dashboard => write!(f, "Dashboard"),
            NodeType::Automation => write!(f, "Automation"),
        }
    }
}

#[derive(Debug, Serialize, Deserialize)]
pub struct SearchRequestParams {
    r#type: NodeType,
    permissions: Vec<u8>,
    query: Option<String>,
}

impl SearchRequestParams {
    pub fn new(
        r#type: NodeType,
        permissions: Vec<u8>,
        query: Option<String>,
    ) -> SearchRequestParams {
        Self {
            r#type,
            permissions,
            query,
        }
    }
    pub fn into_params(&self) -> String {
        // let p = self.permissions.iter().map(|v| v.to_string()).collect::<String>();
        format!(
            "?type={}&permissions={}{}",
            self.r#type,
            format!(
                "[{}]",
                self.permissions
                    .iter()
                    .map(|v| v.to_string())
                    .collect::<Vec<String>>()
                    .join(",")
            ),
            match &self.query {
                Some(query) => format!("&query={}", query),
                None => "".into(),
            }
        )
    }
}

#[derive(Debug, Serialize, Deserialize)]
pub enum Permission {
    Manager = 0,
    Editor = 1,
    UpdateOnly = 2,
    ReadOnly = 3,
}

impl From<u8> for Permission {
    fn from(value: u8) -> Self {
        match value {
            0 => Permission::Manager,
            1 => Permission::Editor,
            2 => Permission::UpdateOnly,
            3 => Permission::ReadOnly,
            _ => Permission::ReadOnly,
        }
    }
}

#[derive(Debug, Serialize, Deserialize)]
pub struct NodesRespSchema {
    pub nodes: Vec<Node>,
}

pub struct NodesManager {
    pub space_id: String,
    pub config: Config,
}

impl NodesManager {
    pub async fn query_all(&self) -> anyhow::Result<Vec<Node>> {
        let url = format!("{}/spaces/{}/nodes", self.config.get_url(), self.space_id);
        let client = reqwest::Client::new();
        let resp = client
            .get(&url)
            .headers(self.config.clone().into())
            .send()
            .await?
            .json::<ResponseSchema<NodesRespSchema>>()
            .await?;

        match resp.code {
            200 => anyhow::Ok(resp.data.unwrap().nodes),
            _ => Err(anyhow::Error::msg(format!(
                "code: {}, success: {}, message: {}, request_url: {}",
                resp.code, resp.success, resp.message, url
            ))),
        }
    }

    pub async fn node(&self, node_id: &str) -> anyhow::Result<Node> {
        let url = format!(
            "{}/spaces/{}/nodes/{}",
            self.config.get_url(),
            self.space_id,
            node_id
        );
        let client = reqwest::Client::new();
        let resp = client
            .get(&url)
            .headers(self.config.clone().into())
            .send()
            .await?
            .json::<ResponseSchema<Node>>()
            .await?;

        match resp.code {
            200 => anyhow::Ok(resp.data.unwrap()),
            _ => Err(anyhow::Error::msg(format!(
                "code: {}, success: {}, message: {}, request_url: {}",
                resp.code, resp.success, resp.message, url
            ))),
        }
    }
    //the api does not work now
    pub async fn search_node(&self, sr: SearchRequestParams) -> anyhow::Result<Vec<Node>> {
        let mut config = self.config.clone();
        config.set_version("v2");
        let url = format!(
            "{}/spaces/{}/nodes/{}",
            config.get_url(),
            self.space_id,
            sr.into_params()
        );
        dbg!("{}", &url);
        let client = reqwest::Client::new();
        let resp1 = client
            .get(&url)
            .headers(self.config.clone().into())
            .send()
            .await?
            .json::<serde_json::Value>()
            .await?;
        dbg!("{}:?", &resp1);

        let resp = client
            .get(&url)
            .headers(self.config.clone().into())
            .send()
            .await?
            .json::<ResponseSchema<NodesRespSchema>>()
            .await?;

        match resp.code {
            200 => anyhow::Ok(resp.data.unwrap().nodes),
            _ => Err(anyhow::Error::msg(format!(
                "code: {}, success: {}, message: {}, request_url: {}",
                resp.code, resp.success, resp.message, url
            ))),
        }
    }
}