Rust + FISCO BCOS
2 创建新的 Rust 项目
- 创建项目
webase-interactor-example
cargo new webase-interactor-example
- 更新目录结构
在这次学习中,我们引入更复杂的项目结构,我们会在项目中创建一个lib并引用它,做到模块解耦。
我们进入项目目录并在项目下创建一个lib:
cd webase-interactor-example cargo new webase-interactor --lib
我们再创建一个文件,在webase-interactor/src目录下创建chain.rs
。
这样,我们得到了这样的目录结构:
. ├── Cargo.toml ├── src │ └── main.rs └── webase-interactor ├── Cargo.toml └── src ├── chain.rs └── lib.rs
3 编写webase-interactor
库
3.1 编写webase-interactor
的Cargo.toml
webase-interactor
的Cargo.toml
如下:
[package] name = "webase-interactor" version = "0.1.0" authors = ["leeduckgo <albertschr@163.com>"] edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] reqwest = { version = "0.10", features = ["blocking", "json"] } tokio = { version = "0.2", features = ["full"] }
我们在此引入了reqwest
这个HTTP
库。
An ergonomic, batteries-included HTTP Client for Rust.
https://github.com/seanmonstar/reqwest
reqwest
支持同步/异步的http
调用,在本实例中,我们使用同步方案。
3.2 编写chain.rs
chain.rs
的内容如下:
pub struct Chain{ ip: String, } impl Chain{ pub fn new(ip: String) -> Chain { Chain { ip } } pub fn get_ip(&self) -> String { self.ip.to_string() } pub fn get_block_number(&self) -> Result<String, reqwest::Error>{ let mut url =self.ip.to_string(); url += &"WeBASE-Front/1/web3/blockNumber/".to_string(); let resp = reqwest::blocking::get(&url)? // .await? .text(); // .await?; resp } }
3.2.1 结构体
我们先定义了一个结构体,关于结构体更详细的介绍请见如下两个链接:
https://www.runoob.com/rust/rust-struct.html
https://kaisery.github.io/trpl-zh-cn/ch05-01-defining-structs.html
在 Rust 中,Struct 语句仅用来定义,不能声明实例,结尾不需要;
符号,而且每个字段定义之后用 ,
分隔。
如,定义一个矩形:
struct Rectangle { width: u32, height: u32, }
在本项目中,我们定义了一个结构体Chain
,这个结构体有一个参数ip
,我们可以通过这个参数定位到相应的webase
。
3.2.2 结构体方法
如同在面向对象的编程语言中,函数挂载在类(Class)的里面一样,在 Rust 中,我们可以将函数挂载在结构体里面。
如,实现一个结构体函数area
,计算出矩形的面积。
impl Rectangle { fn area(&self) -> u32 { self.width * self.height } }
在本项目中,我们定义了如下方法:
new
方法:创建一个新的Chain。get_ip
方法:获取Chain实例的ip。get_block_number
方法:通过和Webase交互,获取当前块高。
在get_block_number
方法中,我们拼接出url字符串,然后调用reqwest
的get
函数。
get
函数的返回值是Result<String, reqwest::Error>
,所以我们的函数结构是这样的:
pub fn get_block_number(&self) -> Result<String, reqwest::Error>{ //注意不要遗漏 &self // do sth resp // 在 rust 中,我们无需return关键字,最后一行不带;,执行的结构即函数返回值。 }
3.3 编写lib.rs
lib.rs
内容如下:
//! # WeBase //! //! A library to interact with webase. #![warn(unused_extern_crates)] pub mod chain; pub use self::chain::*;
这里我们把chain
声明为一个命名空间。
mod还支持多级嵌套,如:
// phrases.rs pub mod english { pub mod greetings { pub fn hello() { println!("Hello!") } pub fn hey_guies() { println!("Hey, guies!") } } pub mod farewells { pub fn goodbye() { println!("Goodbye!") } pub fn see_you() { println!("See you!") } } } pub mod chinese { pub mod greetings { pub fn hello() { println!("你好!") } pub fn have_eaten() { println!("吃了么?") } } pub mod farewells { pub fn goodbye() { println!("再见!") } pub fn everyone_will_know_you() { println("天下谁人不识君!") } } }
这样来管理我们的模块,我们的代码在各种意义上都会更清晰。
4 完成主项目
4.1 编写Cargo.toml
主项目的Cargo.toml
如下:
[package] name = "webase-interactor-example" version = "0.1.0" authors = ["leeduckgo <albertschr@163.com>"] edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] pretty_env_logger = "0.3" log = "0.4" reqwest = { version = "0.10", features = ["json"] } tokio = { version = "0.2", features = ["full"] } webase-interacter = { path="./webase-interactor", version = "0.1.0"}
在本项目中,我们引入了pretty_env_logger
,以便更好的进行输出。
除此之外,我们还引入了刚才创建的webase-interactor
。
4.2 编写main.rs
main.rs
的内容如下:
extern crate pretty_env_logger; use webase_interactor::Chain; #[macro_use] extern crate log; fn main(){ pretty_env_logger::init(); print_block_number(); } pub fn print_block_number() { let ip = "http://127.0.0.1:5002/".to_string(); let chain = Chain::new(ip); let res = chain.get_block_number(); match res { Err(e) => { println!("error: {}", e); } Ok(b_number) => { info!("last block height: {}", b_number); } } }
到此为止,我们的代码已经全部编写完成了。
编译:
cargo build
执行:
RUST_LOG=info cargo run
如期打印出当前块高。
我们在cargo run
命令前加上RUST_LOG=info
,所以我们在输出的时候仅会打印info!
函数中的内容。
本系列所有源码见:
https://github.com/leeduckgo/RustStudy