df-plugin 0.1.0

This is an Plugin
Documentation
use std::{env, fs};
use std::fs::File;
use std::io::Write;
use std::path::Path;
use json::{JsonValue, object};
use df_cache::Cache;
use df_db::db::ModeDb;
use df_db::model::ModelTable;
use crate::tests::test::test::TestAction;
use crate::tests::test::TestModel;
use crate::tests::TestPlugin;

pub mod tests;

/// 内部插件入口
pub fn plugins(name: &str) -> Box<dyn Plugin> {
    match name {
        _ => Box::new(TestPlugin {})
    }
}

/// 内部模型入口
pub fn models(name: &str) -> Box<dyn Model> {
    match name {
        _ => Box::new(TestModel {})
    }
}

/// 内部动作入口
pub fn actions(name: &str) -> Box<dyn Action> {
    match name {
        _ => Box::new(TestAction { model: TestModel {} })
    }
}


/// 插件
pub trait Plugin {
    fn model(&mut self, name: &str) -> Box<dyn Model>;
}

/// 模型
pub trait Model {
    /// 版本号
    fn version(&mut self) -> String {
        return "0.0.1".to_string();
    }
    /// 数据库表名称
    fn table(&mut self) -> String;
    /// 模型名称
    fn title(&mut self) -> String;
    /// 字段列表
    fn fields(&mut self) -> JsonValue;

    /// 数据库唯一约束
    fn unique(&mut self) -> Vec<String> {
        return vec![];
    }
    /// 查询索引
    fn index(&mut self) -> Vec<Vec<String>> {
        return vec![];
    }
    /// 主键
    fn primary_key(&mut self) -> String {
        return "id".to_string();
    }
    /// 自动ID值
    fn auto(&mut self) -> bool {
        return false;
    }
    /// 创建安装json
    fn json(&mut self) -> ModelTable {
        ModelTable {
            version: self.version(),
            table: self.table(),
            title: self.title(),
            primary_key: self.primary_key(),
            auto: self.auto(),
            unique: self.unique(),
            index: self.index(),
            fields: self.fields(),
        }
    }
    /// 创建安装文件
    fn create_json_file(&mut self, path: &str) -> bool {
        let json = self.json();
        let o = Path::new(path);
        if !o.is_dir() {
            fs::create_dir(path).unwrap();
        }
        env::set_current_dir(path).unwrap();
        let dir = env::current_dir().unwrap();
        let version = self.version();
        let version = version.replace(".", "_");
        let dir = dir.join(format!("{}_{}.json", self.table(), version));
        let mut f = File::create(dir.to_str().unwrap()).unwrap();
        match f.write_all(json.to_string().as_bytes()) {
            Ok(_) => true,
            Err(_) => false
        }
    }
    /// 模型动作
    fn action(&mut self, name: &str) -> Box<dyn Action>;
}

/// 动作
pub trait Action {
    /// 标题
    fn title(&mut self) -> String;
    /// api名称
    fn name(&mut self) -> String;
    /// 求求方式
    fn method(&mut self) -> String { "post".to_string() }
    /// 是否使用密钥
    fn token(&mut self) -> bool { true }
    /// 请求参数入口
    fn params(&mut self) -> JsonValue { object! {} }
    /// 检测
    fn _check(&mut self, mut request: JsonValue) -> (bool, String, JsonValue) {
        let params = self.params();
        let mut new_request = object! {};
        for (key, field) in params.entries() {
            if request[key].is_empty() && field["require"].as_bool().unwrap() {
                return (false, format!("缺少参数 {}:{}", key, field["title"]), request);
            }
            if request[key].is_empty() && !field["require"].as_bool().unwrap() {
                request[key] = field["def"].clone().into()
            }
            new_request[key] = request[key].clone();
        }
        return (true, format!("验证通过"), new_request);
    }
    /// 执行参数入口
    fn run(&mut self, header: JsonValue, request: JsonValue, db: ModeDb, cache: Cache) -> Response {
        let (state, msg, request) = self._check(request.clone());
        if !state {
            return self.fail(-1, request, msg.as_str().clone());
        }
        return self.index(header, request, db, cache);
    }
    fn index(&mut self, header: JsonValue, request: JsonValue, db: ModeDb, cache: Cache) -> Response;

    fn success(&mut self, code: i32, data: JsonValue, msg: &str) -> Response {
        Response {
            code,
            data,
            msg: msg.to_string(),
        }
    }

    fn fail(&mut self, code: i32, data: JsonValue, msg: &str) -> Response {
        Response {
            code,
            data,
            msg: msg.to_string(),
        }
    }
}

pub struct Response {
    code: i32,
    data: JsonValue,
    msg: String,
}

impl Response {
    pub fn to_json(self) -> JsonValue {
        let mut res = object! {};
        res["code"] = self.code.into();
        res["data"] = self.data.into();
        res["msg"] = self.msg.into();
        res
    }
    pub fn success(code: i32, data: JsonValue, msg: &str) -> Self {
        Self {
            code,
            data,
            msg: msg.to_string(),
        }
    }

    pub fn fail(code: i32, data: JsonValue, msg: &str) -> Self {
        Self {
            code,
            data,
            msg: msg.to_string(),
        }
    }
}