[易学易懂系列|rustlang语言|零基础|快速入门|(28)|实战5:实现BTC价格转换工具]

项目实战

实战5:实现BTC价格转换工具

今天我们来开发一个简单的BTC实时价格转换工具。

我们首先创建一个目录:

cargo new btc_converter

我们用TDD方式来开发。

然后 我们先写一些测试代码。

在src/main.rs下面,增加代码如下:

#[cfg(test)]
mod tests {
use super::*; #[test]
fn test_convert_success() {
match convert_btc(1.2, "BTC", "USD") {
Ok(_) => assert!(true),
Err(_) => assert!(false),
}
}
#[test]
fn test_convert_success2() {
match convert_btc(2.1, "BTC", "MKD") {
Ok(_) => assert!(true),
Err(_) => assert!(false),
}
} #[test]
fn test_convert_error_wrong_from() {
match convert_btc(1.2, "wrongvalue", "USD") {
Ok(_) => assert!(false),
Err(_) => assert!(true),
}
} #[test]
fn test_convert_error_wrong_to() {
match convert_btc(1.2, "USD", "wrongvalue") {
Ok(_) => assert!(false),
Err(_) => assert!(true),
}
}
}

我们运行命令:

cargo test

结果肯定是不通过。

我现在我们来增加核心业务代码 :

const API_URL: &str = "https://apiv2.bitcoinaverage.com/convert/global";

//错误信息
#[derive(From, Display, Debug)]
enum BtcError {
ApiError,
Reqwest(reqwest::Error),
}
//响应信息结构体
#[derive(Deserialize, Debug)]
struct BtcResponse {
time: String,
success: bool,
price: f64,
} //价格转换,直接调用相关API
fn convert_btc(amount: f64, from: &str, to: &str) -> Result<BtcResponse, BtcError> {
use BtcError::*;
println!("---convert_btc-----{:?},{:?}", from, to);
let client = reqwest::Client::new();
let request =
client
.get(API_URL)
.query(&[("from", from), ("to", to), ("amount", &amount.to_string())]);
let response_result: BtcResponse = request.send()?.json()?; if !response_result.success {
return Err(ApiError);
} return Ok(response_result);
}

然后,我们再跑一下测试用例。

现在应该都通过 了。

当然我们要引用相关包:

[dependencies]
reqwest = "0.9.12"
serde_derive = "1.0.89"
serde = "1.0.89"
serde_json = "1.0.39"
structopt = "0.2.15"
derive_more = "0.14.0"

src/main.rs完整代码如下:

#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate derive_more;
use reqwest;
use std::process::exit;
use structopt::StructOpt; fn main() {
let opt = Opt::from_args(); let response = match convert_btc(opt.amount, &opt.from, &opt.to) {
Ok(value) => value,
Err(e) => {
println!("A error occurred when try to get value from api");
if opt.verbose {
println!("Message: {} - Details: {:?}", e, e);
}
exit(1);
}
}; if opt.silent {
println!("{}", response.price);
} else {
println!("{} {}", response.price, &opt.to);
}
}
const API_URL: &str = "https://apiv2.bitcoinaverage.com/convert/global";
//错误信息
#[derive(From, Display, Debug)]
enum BtcError {
ApiError,
Reqwest(reqwest::Error),
}
//响应信息结构体
#[derive(Deserialize, Debug)]
struct BtcResponse {
time: String,
success: bool,
price: f64,
} #[derive(Debug, StructOpt)]
#[structopt(
name = "btc_converter",
about = "Get value of a btc value to a currency"
)]
struct Opt {
/// Set amount to convert to a currency or from a currency
#[structopt(default_value = "1")]
amount: f64,
/// Set the initial currency of
#[structopt(short = "f", long = "from", default_value = "BTC")]
from: String,
/// Set the final currency to convert
#[structopt(short = "t", long = "to", default_value = "USD")]
to: String,
/// Silent information about currency result
#[structopt(short = "s", long = "silent")]
silent: bool,
/// Verbose errors
#[structopt(short = "v", long = "verbose")]
verbose: bool,
}
fn convert_btc(amount: f64, from: &str, to: &str) -> Result<BtcResponse, BtcError> {
use BtcError::*;
println!("---convert_btc-----{:?},{:?}", from, to);
let client = reqwest::Client::new();
let request =
client
.get(API_URL)
.query(&[("from", from), ("to", to), ("amount", &amount.to_string())]);
let response_result: BtcResponse = request.send()?.json()?; if !response_result.success {
return Err(ApiError);
} return Ok(response_result);
}
#[cfg(test)]
mod tests {
use super::*; #[test]
fn test_convert_success() {
match convert_btc(1.2, "BTC", "USD") {
Ok(_) => assert!(true),
Err(_) => assert!(false),
}
}
#[test]
fn test_convert_success2() {
match convert_btc(2.1, "BTC", "MKD") {
Ok(_) => assert!(true),
Err(_) => assert!(false),
}
} #[test]
fn test_convert_error_wrong_from() {
match convert_btc(1.2, "wrongvalue", "USD") {
Ok(_) => assert!(false),
Err(_) => assert!(true),
}
} #[test]
fn test_convert_error_wrong_to() {
match convert_btc(1.2, "USD", "wrongvalue") {
Ok(_) => assert!(false),
Err(_) => assert!(true),
}
}
}

API地址:

https://apiv2.bitcoinaverage.com

以上,希望对你有用。

如果遇到什么问题,欢迎加入:rust新手群,在这里我可以提供一些简单的帮助,加微信:360369487,注明:博客园+rust

[易学易懂系列|rustlang语言|零基础|快速入门|(28)|实战5:实现BTC价格转换工具]的更多相关文章

  1. [易学易懂系列|rustlang语言|零基础|快速入门|(27)|实战4:从零实现BTC区块链]

    [易学易懂系列|rustlang语言|零基础|快速入门|(27)|实战4:从零实现BTC区块链] 项目实战 实战4:从零实现BTC区块链 我们今天来开发我们的BTC区块链系统. 简单来说,从数据结构的 ...

  2. [易学易懂系列|rustlang语言|零基础|快速入门|(26)|实战3:Http服务器(多线程版本)]

    [易学易懂系列|rustlang语言|零基础|快速入门|(26)|实战3:Http服务器(多线程版本)] 项目实战 实战3:Http服务器 我们今天来进一步开发我们的Http服务器,用多线程实现. 我 ...

  3. [易学易懂系列|rustlang语言|零基础|快速入门|(25)|实战2:命令行工具minigrep(2)]

    [易学易懂系列|rustlang语言|零基础|快速入门|(25)|实战2:命令行工具minigrep(2)] 项目实战 实战2:命令行工具minigrep 我们继续开发我们的minigrep. 我们现 ...

  4. [易学易懂系列|rustlang语言|零基础|快速入门|(24)|实战2:命令行工具minigrep(1)]

    [易学易懂系列|rustlang语言|零基础|快速入门|(24)|实战2:命令行工具minigrep(1)] 项目实战 实战2:命令行工具minigrep 有了昨天的基础,我们今天来开始另一个稍微有点 ...

  5. [易学易懂系列|rustlang语言|零基础|快速入门|(23)|实战1:猜数字游戏]

    [易学易懂系列|rustlang语言|零基础|快速入门|(23)|实战1:猜数字游戏] 项目实战 实战1:猜数字游戏 我们今天来来开始简单的项目实战. 第一个简单项目是猜数字游戏. 简单来说,系统给了 ...

  6. [易学易懂系列|rustlang语言|零基础|快速入门|(5)|生命周期Lifetime]

    [易学易懂系列|rustlang语言|零基础|快速入门|(5)] Lifetimes 我们继续谈谈生命周期(lifttime),我们还是拿代码来说话: fn main() { let mut a = ...

  7. [易学易懂系列|rustlang语言|零基础|快速入门|(22)|宏Macro]

    [易学易懂系列|rustlang语言|零基础|快速入门|(22)|宏Macro] 实用知识 宏Macro 我们今天来讲讲Rust中强大的宏Macro. Rust的宏macro是实现元编程的强大工具. ...

  8. [易学易懂系列|rustlang语言|零基础|快速入门|(21)|智能指针]

    [易学易懂系列|rustlang语言|零基础|快速入门|(21)|智能指针] 实用知识 智能指针 我们今天来讲讲Rust中的智能指针. 什么是指针? 在Rust,指针(普通指针),就是保存内存地址的值 ...

  9. [易学易懂系列|rustlang语言|零基础|快速入门|(20)|错误处理]

    [易学易懂系列|rustlang语言|零基础|快速入门|(20)|错误处理] 实用知识 错误处理 我们今天来讲讲Rust中的错误处理. 很多语言都有自己的错误处理方式,比如,java是异常处理机制. ...

随机推荐

  1. 【Matlab开发】matlab中norm范数以及向量点积、绘图设置相关

    [Matlab开发]matlab中norm范数以及向量点积.绘图设置相关 标签(空格分隔): [Matlab开发] 声明:引用请注明出处http://blog.csdn.net/lg125915677 ...

  2. 36.HTTP协议

    HTTP简介 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送 ...

  3. MSSQL 获取数据库、表、字段信息语句

    --获取所有数据库名称 SELECT Name FROM Master..SysDatabases ORDER BY Name --获取库里所有表名 SELECT * FROM SysObjects ...

  4. P61IDEA的常用快捷键

    Alt+Enter   导入包,自动修正代码 Ctrl+Y  删除光标所在行 Ctrl+D 复制光标所在行的内容,插入光标位置下面 Ctrl+Alt+L  格式化代码 Ctrl+/   单行注释 Al ...

  5. PHP搭建B2C分销商城系统需要考虑哪些因素?(一)

    在网购日渐繁盛的今天,传统线下门店和代理分销越发显示出其弊端.此种情况下,进入互联网市场是最好的选择.入驻第三方平台成本太高,无法掌握自己的流量,所以搭建自己的分销平台成为众多企业的首选.搭建B2C分 ...

  6. Till I Collapse CodeForces - 786C (主席树区间加,二分最小值)

    大意: 给定序列, 将序列划分为若干段, 使得每段不同数字不超过k, 分别求出k=1...n时的答案. 考虑贪心, 对于某个k 从1开始, 每次查询最后一个颜色数<=k的点作为一个划分, 直到全 ...

  7. redis 入门教程

    https://edu.aliyun.com/course/22/lesson/list?spm=5176.8252056.759075.5.Bbrpyz

  8. 怎样理解undefined和 null

    前言: undefined表示 "未定义", null 表示 "空" 第一步: 一般在变量或属性没有声明或者声明以后没有赋值时, 这个变量的值就是undefin ...

  9. MVC部分视图的使用(Html.Partial/RenderPartial、Html.Action/RenderAction、RenderPage)

    ASP.NET MVC 里页面往往会有许多重用的地方,可以进行封装重用. 使用部分视图有以下优点: 1. 可以简写代码. 2. 页面代码更加清晰.更好维护. 在视图里有多种方法可以 加载部分视图,包括 ...

  10. vue2.0和animate.css的结合使用

    animate.css是一款前端动画库,相似的有velocity-animate. 上述是一个完整的结构.其中重要的几个点用箭头表示出来.首先在transition组件内部,需要定义两个基本的clas ...