前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Rust 日报】2021-08-15 jsonschema-rs:Rust 的 Json 校验工具

【Rust 日报】2021-08-15 jsonschema-rs:Rust 的 Json 校验工具

作者头像
MikeLoveRust
发布2021-09-08 10:01:19
7570
发布2021-09-08 10:01:19
举报
文章被收录于专栏:Rust语言学习交流

jsonschema-rs:Rust Json 校验工具

如果你没有听(用)过 Json Schema,请允许我首先简单介绍一下。JSON Schema 是用于验证 JSON 数据结构的工具,如果你厌恶对 Json 数据各种 if else 的判断和校验,那该工具非常适合。它的官网:JSON Schema | The home of JSON Schema,先看一个简单的例子,假设我们有下面的 Schema:

代码语言:javascript
复制
{
  "type": "object",
  "properties": {
    "first_name": { "type": "string" },
    "last_name": { "type": "string" },
    "birthday": { "type": "string", "format": "date" },
    "address": {
      "type": "object",
      "properties": {
        "street_address": { "type": "string" },
        "city": { "type": "string" },
        "state": { "type": "string" },
        "country": { "type" : "string" }
      }
    }
  }
}

这个 Schema 一共定义了四个字段,每个字段的类型都做了规定,address 本身也是一个 Json Object。此时,有效的数据是:

代码语言:javascript
复制
{
  "first_name": "George",
  "last_name": "Washington",
  "birthday": "1732-02-22",
  "address": {
    "street_address": "3200 Mount Vernon Memorial Highway",
    "city": "Mount Vernon",
    "state": "Virginia",
    "country": "United States"
  }
}

而下面这样的无效数据则会被 Json Schema 验证并报错:

代码语言:javascript
复制
{
  "name": "George Washington",
  "birthday": "February 22, 1732",
  "address": "Mount Vernon, Virginia, United States"
}

Json Schema 本身是语言无关的,这里已经有很多实现了:Implementations | JSON Schema,Rust 版本的使用与其他语言类似:

代码语言:javascript
复制
use jsonschema::{Draft, JSONSchema};
use serde_json::json;

fn main() {
    let schema = json!({"maxLength": 5});
    let instance = json!("foo");
    # 编译 Schema
    let compiled = JSONSchema::compile(&schema)
        .expect("A valid schema");
    # 验证实例
    let result = compiled.validate(&instance);
    if let Err(errors) = result {
        for error in errors {
            println!("Validation error: {}", error);
            println!(
                "Instance path: {}", error.instance_path
            );
        }
    }
}

这个工具唯一有个麻烦的地方就是编写 Schema 比较费劲,可以理解为设计类。不过好在写好之后就省事了。

GitHub:Stranger6667/jsonschema-rs: JSON Schema validation library

vec-const:允许将 vecs 声明为 consts

用法如下:

代码语言:javascript
复制
pub struct AThing(u8, &'static str);

const A_VEC_CONST: ManuallyDrop<Vec<AThing>> = vec_const!(AThing, AThing(5, "wow"), AThing(2, "cool"));

fn main()
{
    assert_eq!(*TEST, vec!(AThing(5, "wow"), AThing(2, "cool")));
}

GitHub:Eolu/vec-const: Rust crate to allow declaration of vecs as consts

cargo-auto:自动任务工具

包括:构建、发布、文档等功能。Cargo 功能已经很强大了,为啥还要做这个东西呢?因为有时我们需要做更多的事情,比如复制一些文件、发布到 ftp 或输入长命令。这些重复性任务必须自动化(也称为 “工作流自动化”)。

代码语言:javascript
复制
$ cargo install cargo-auto
$ cargo auto new
$ cargo auto build
$ cargo auto release
$ cargo auto docs

GitHub:LucianoBestia/cargo-auto: cargo auto - automation tasks written in Rust language

rillrate 新版本发布

RillRate 是完全使用 Rust 和 Yew 框架制作的机器人、微服务和物联网的快速 UI。全栈 Rust 是真实存在的!

本周增加的新功能:

  • 新控件:按钮、开关、选择器和滑块。
  • 新数据类型:表格、仪表、直方图(尚未图形化)。

GitHub:rillrate/rillrate: Dynamic UI for bots, microservices, and IoT.

for_ch:一个展平嵌套的 for 循环和 if-let 的 macro

具体使用方式如下:

代码语言:javascript
复制
for_ch! {
    for x in 0..10;                         // forall x in 0..10,
    // you can add a label before `for`
    for y in x..10, for _ in 0..5;          // forall y in x..x+5, 
    // zipping
    if let Some(z) = foo(x, y).await?;      // exists z. Some(z) = foo(x, y).await?
    // if let guard
    if x - y < z;                           // satisfies x - y < z
    // guard
    println!("x = {}, y = {}, z = {}", x, y, z);
}
# 结果为
for x in 0..10 {
    for y in (x..10).zip(0..5) {
        if let Some(z) = foo(x, y).await? {
            if x - y < z {
                println!("x = {}, y = {}, z = {}", x, y, z);
            }
        }
    }
}

不过,谁会这么写代码呢,完全没有可读性嘛,看来只能用来装逼了。

GitHub:TOETOE55/for_ch: A macro to write nested for loop

identity_cast:动态地对类型专门化

该库提供了通过 Any 动态地对类型进行专门化的函数。基本思想是,如果 T 和 U 实际上是同一类型,则允许将任何 T “强制转换” 为任何其他 U。

代码语言:javascript
复制
use identity_cast::IdentityCast;

fn print_i32_specially<T: 'static>(v: T) {
    match v.into_same::<i32>() {
        Ok(v) => {
            println!("This is a `i32` with value {}", v);
        }
        Err(_) => {
            println!("This is some `T`");
        }
    }
}
print_i32_specially("123");
# This is some `T`
print_i32_specially(123);
# This is a `i32` with value 123

GitHub:Kimundi/identity_cast


From 日报小组 长琴

社区学习交流平台订阅:

  • Rustcc 论坛:支持 rss
  • 微信公众号:Rust 语言中文社区
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-08-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Rust语言学习交流 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • jsonschema-rs:Rust Json 校验工具
  • vec-const:允许将 vecs 声明为 consts
  • cargo-auto:自动任务工具
  • rillrate 新版本发布
  • for_ch:一个展平嵌套的 for 循环和 if-let 的 macro
  • identity_cast:动态地对类型专门化
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档