狗哥区块链与AI精品内容集@NonceGeek

2025年03月28日更新 75 人订阅
原价: ¥ 20 限时优惠
专栏简介 「造」最关键的是什么?| Hackathon 漫游指南(贰) Why Hackathon?| Hackathon 漫游指南(壹) 设计「众人维护」的 BuidlerBoard | BeWater.xyz Movement 白皮书中文版 Rebuidl RSS 生产因素与反生产因素 | 独立黑客创业手册(陆) 组织 | 独立黑客创业手册(伍) 生产 | 独立黑客创业手册(肆) 销售 | 独立黑客创业手册(叄) 最优先的能力 | 独立黑客创业手册(贰) 为什么从独立黑客开始 | 独立黑客创业手册(壹) Aptos Token Object V2 | Move dApp 极速入门(贰拾肆) 可編程交易塊 | Move dApp 極速入門(貳拾叁) Aptos 密鑰輪換 | Move dApp 極速入門(貳拾貳) Aptos 对象模型 | Move dApp 极速入门(贰拾壹) Aptos Moveflow SDK使用指南 | Move dApp 极速入门(贰拾) Sui 上简单 Swap 的实现 | Move dApp 极速入门(拾玖) 用 Elixir 交互 Aptos | Move dApp 极速入门(拾捌) Sui 链上数据查询 | Move dApp 极速入门(拾柒) SUI 合约测试攻略 | Move dApp 极速入门(拾陆) Sui 数据类型详解 | Move dApp 极速入门(拾伍) Airdropper Contract in Aptos | Move dApp 极速入门(拾肆) Sandwich合约源码解析 | Move dApp 极速入门(拾叁) Sui 极速上手 | Move dApp 极速入门(拾贰) scaffold-aptos 脚手架 | Move dApp 极速入门(拾壹) 对 DID Document 的思考 | Move dApp 极速入门(九) DID中地址聚合器的实现 | Move dApp 极速入门(八) 值的存取应用3.0 | Web3.0 dApp 开发(五) 合约数据类型综述 | Move dApp 极速入门(四) 操作资源 | Move dApp 极速入门(三) 第一个 Move dApp | Move dApp 极速入门(二) Hello Move | Move dApp极速入门(一) Staker | Web3.0 dApp 开发(九) Token 自动售卖机 | Web3.0 dApp 开发(七) SVG NFT 全面实践 | Web3.0 dApp 开发(六) 值的存取应用2.0 | Web3.0 dApp 开发(四) 值的存取应用1.0 | Web3.0 dApp开发(三) Scaffold-eth 快速上手 | Web3.0 dApp 开发(二) eth.build 快速上手 | Web3.0 dApp 开发(一) 1 小时理解比特币系统 【NonceGeek Workshop 0x01总结】基于链上数据生成游戏地图 Remix 完全本地化部署 NFT:实体与虚拟载体的主与辅 | 狗哥的元宇宙思辨(一) Web3Camp 内容大全@NonceGeek 用 Python 创建一条 Pow 区块链(上) 区块链与共识机制演变史 基于 Etherscan 实现 Blockchain Syncer 【论文分享】去中心化社会:寻找 Web3 的灵魂(上) 【论文分享】去中心化社会:寻找 Web3 的灵魂(下) Ted Yin | 2021 年的区块链基础设施将是什么? 0. 公链、联盟链与分布式未来(全文) 基于 Infura 与 Web3py 部署调用 Hello 合约全过程 | 以太坊开发极速入门 太上中的基因设计与Binary | 函数式与区块链(一) 理解以太坊合约数据读取过程 | 函数式与区块链(二) Hello, Ink! | 用 Rust 写智能合约(一) Mapping 数据结构 | 用 Rust 写智能合约(二) 用 Rust 程序和 Webase 交互 | Rust 学习笔记(四) 用 Sqlite 存储 WeId | Rust 学习笔记(五) 链上注册WeId与错误处理 | Rust 学习笔记(六) WeId 链上创建与本地存储的完整闭环 | Rust 学习笔记(七) 以太坊上的核心开发者 Austin | 以太坊上的最佳开发实践 1. FISCO BCOS 开发环境节点搭建全攻略 伪代码简述 ECDSA 签名过程 | 联盟链开发 WeIdentity 源码分析 | 狗哥解码 WeIdentity 源码分析 | 狗哥解码 FISCO BCOS 介绍 | 联盟链开发 给Remix升个级 | 联盟链开发 2. 控制台的安装与使用 3. 【实验】补全一个区块链应用 4. 控制台的Web化 5. Web化控制台2.0:打造团队共用区块链学习平台 6. 使用脚手架快速搭建 Java DApp 【视频+文字】分布式思维 Rebuidl RSS (EN)

链上注册WeId与错误处理 | Rust 学习笔记(六)

  • 李大狗
  • 发布于 2021-05-29 17:41
  • 阅读 4602

老细,我要Handle All the Error啊!

系列简介:狗哥 Rust 学习笔记系列是大狗为对抗 Rust 陡峭的学习曲线而推出的 Rust 学习系列,具备如下原则:

  1. 循序渐进原则

按照阶梯法则(下一篇的难度是上一篇难度+1)原则进行设计,让学习 Rust 跟打游戏一样简单。

  1. 单一知识点原则

一篇文章只讲一个一个知识点,保证简单性与专注性。

  1. 实用原则

所有案例均是真实实践案例,实用性超强。

上一篇文章里,我们开启了weid-rust-example项目,学习了如何通过diesel项目玩转SQLite数据库。今天我们依然在这个项目的基础上往前推进。

实现功能

我们将围绕结构体Struct WeId,实现create_weid_online函数:

#[derive(Default)]
pub struct WeId{
    endpoint_url: String,
    weid: String, 
}

impl WeId{
    pub fn create_weid_online(&self) -> ... {

  }
}

和以往我们实现过的函数不同的是,在这个函数中,我们可以遇到多种可能的错误(Error),因此,在返回值里我们就不能向过去一样,填写Result<Value, reqwest::Error>,我们需要通过一个枚举(Enum)把可能的错误打包在一起。

Let's Go!

create_weid_online 函数拆解

在函数式编程中,我们会遵循「单一职责原则」,简单来说,就是一个函数只做一件事。因此,即使create_weid_online是简单的函数,我们依然可以将其拆分:

create_weid_online —— 子函数的组合
    |------ call_create_weid —— 通过weid-rest-service的接口注册托管型 weid 并获得返回值
    |------ str_to_json —— 将 &str 值转换为 json

子函数的实现

str_to_json函数:

fn str_to_json(&self, payload: &str) -> Result<Value, serde_json::Error> {
    serde_json::from_str(payload)
}

这个函数中使用了serde_json库,在Cargo.toml为:

[dependencies]
...
serde_json = { version = "1.0" }
...

call_create_weid函数:

pub fn call_create_weid(&self) -> Result<String, reqwest::Error> {
    let mut url =self.endpoint_url.to_string();
    url += &"/weid/api/invoke".to_string();
    // ::blocking:: to block
    let response = reqwest::blocking::Client::new()
    .post(&url)
    .json(&serde_json::json!({
        "functionArg": {},
        "transactionArg": {},
        "v": "1.0.0",
        "functionName": "createWeId"
    }))
    .send()?
    .text();

    response
}

注:用 Rust 程序和 Webase 交互 | Rust 学习笔记(四)中我们介绍了用 reqwest 调用 get 接口,这次我们调用 post 接口。

这个函数中使用了reqwest库,在Cargo.toml为:

[dependencies]
...
reqwest = { version = "0.10", features = ["blocking", "json"] }
tokio = { version = "0.2", features = ["full"] }
...

WeId-Rest-Service 的接口说明请见:

https://weidentity.readthedocs.io/zh_CN/latest/docs/weidentity-rest-api.html

主函数的实现

以下是create_weid_online函数的源码:

pub fn create_weid_online(&self) -> Result<Value, GenerateWeIdError>{
    let response = self.call_create_weid()?; // line1
    let resp = self.str_to_json(&response)?; // line2
    Ok(resp)
}

我们可以看到,在返回值里的 Error 处,我们填的是自定义的错误类型GenerateWeidError

所以,在line1处可能发生的reqwest::Error错误,和line2处可能发生的serde_json::Error,会被汇集在GenerateWeIdError中。

聚合错误处理的实现

在这里我们使用thiserror这个库,这是目前的最佳处理方案。

Cargo.toml中引用thiserror

[dependencies]
...
thiserror = "1.0"
...

官方的例子是这样的:

use thiserror::Error;

#[derive(Error, Debug)]
pub enum DataStoreError {
    #[error("data store disconnected")]
    Disconnect(#[from] io::Error),
    #[error("the data for key `{0}` is not available")]
    Redaction(String),
    #[error("invalid header (expected {expected:?}, found {found:?})")]
    InvalidHeader {
        expected: String,
        found: String,
    },
    #[error("unknown data store error")]
    Unknown,
}

在这里我们简单使用:

// 记得 enum 要写在 Struct 外面。
#[derive(Error, Debug)]
pub enum GenerateWeIdError {
    #[error("req error")]
    RequestError(#[from] reqwest::Error),
    #[error("parse error")]
    ParseError(#[from] serde_json::Error),
}

这样,就能让GenerateWeIdError囊括这个函数中的所有可能 error 了。

【补充资料】关于 Enum 枚举:

https://kaisery.github.io/trpl-zh-cn/ch06-01-defining-an-enum.html

main函数

main函数中,我们对结构体与函数进行调用:

fn main(){
    let weid = WeId::new("http://127.0.0.1:6001".to_string());
    let result = weid.create_weid_online();
    match result {
        Ok(payload) => println!("{:}", payload),
        Err(e) => println!("{}", e)
    }

执行后,打印出了我们期待的结果: 008i3skNgy1gqwytaoi8cj30o501uq33.png

本项目代码见:

https://github.com/leeduckgo/weid-rust-sample

本系列代码见:

https://github.com/leeduckgo/Rust-Study

点赞 1
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论