[易学易懂系列|rustlang语言|零基础|快速入门|(28)|实战5:实现BTC价格转换工具]
[易学易懂系列|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价格转换工具]的更多相关文章
- [易学易懂系列|rustlang语言|零基础|快速入门|(27)|实战4:从零实现BTC区块链]
[易学易懂系列|rustlang语言|零基础|快速入门|(27)|实战4:从零实现BTC区块链] 项目实战 实战4:从零实现BTC区块链 我们今天来开发我们的BTC区块链系统. 简单来说,从数据结构的 ...
- [易学易懂系列|rustlang语言|零基础|快速入门|(26)|实战3:Http服务器(多线程版本)]
[易学易懂系列|rustlang语言|零基础|快速入门|(26)|实战3:Http服务器(多线程版本)] 项目实战 实战3:Http服务器 我们今天来进一步开发我们的Http服务器,用多线程实现. 我 ...
- [易学易懂系列|rustlang语言|零基础|快速入门|(25)|实战2:命令行工具minigrep(2)]
[易学易懂系列|rustlang语言|零基础|快速入门|(25)|实战2:命令行工具minigrep(2)] 项目实战 实战2:命令行工具minigrep 我们继续开发我们的minigrep. 我们现 ...
- [易学易懂系列|rustlang语言|零基础|快速入门|(24)|实战2:命令行工具minigrep(1)]
[易学易懂系列|rustlang语言|零基础|快速入门|(24)|实战2:命令行工具minigrep(1)] 项目实战 实战2:命令行工具minigrep 有了昨天的基础,我们今天来开始另一个稍微有点 ...
- [易学易懂系列|rustlang语言|零基础|快速入门|(23)|实战1:猜数字游戏]
[易学易懂系列|rustlang语言|零基础|快速入门|(23)|实战1:猜数字游戏] 项目实战 实战1:猜数字游戏 我们今天来来开始简单的项目实战. 第一个简单项目是猜数字游戏. 简单来说,系统给了 ...
- [易学易懂系列|rustlang语言|零基础|快速入门|(5)|生命周期Lifetime]
[易学易懂系列|rustlang语言|零基础|快速入门|(5)] Lifetimes 我们继续谈谈生命周期(lifttime),我们还是拿代码来说话: fn main() { let mut a = ...
- [易学易懂系列|rustlang语言|零基础|快速入门|(22)|宏Macro]
[易学易懂系列|rustlang语言|零基础|快速入门|(22)|宏Macro] 实用知识 宏Macro 我们今天来讲讲Rust中强大的宏Macro. Rust的宏macro是实现元编程的强大工具. ...
- [易学易懂系列|rustlang语言|零基础|快速入门|(21)|智能指针]
[易学易懂系列|rustlang语言|零基础|快速入门|(21)|智能指针] 实用知识 智能指针 我们今天来讲讲Rust中的智能指针. 什么是指针? 在Rust,指针(普通指针),就是保存内存地址的值 ...
- [易学易懂系列|rustlang语言|零基础|快速入门|(20)|错误处理]
[易学易懂系列|rustlang语言|零基础|快速入门|(20)|错误处理] 实用知识 错误处理 我们今天来讲讲Rust中的错误处理. 很多语言都有自己的错误处理方式,比如,java是异常处理机制. ...
随机推荐
- 【OpenCV开发】使用OpenCV的OpenCL(ocl)模块
参加OpenCV的OpenCL模块(以下称OCL)移植工作已经有2个月了.这里我说移植而不是开发,是因为大部分OCL模块的函数都是从已经很成熟的GPU模块移植过来的.于是目前阶段OCL模块所支持的函数 ...
- Charles系列一:Charles功能介绍、下载安装和界面简介
一:Charles主要功能介绍 Charles是一个HTTP代理/HTTP监视器/反向代理,使开发和测试人员能够查看机器和Internet之间所有的HTTP和SSL/HTTPS流量,这包括请求,响应. ...
- IdentityServer4学习记录
前言 .NetCore 生态伴随着各位大神的推广,好多小伙伴都学习或应用到现有项目中了: 同时,很多相关组件也提上了学习之旅,如IdentitiServer4.Polly.Ocelot.Consul ...
- C语言I博客作业12—学期总结
一.我学到的内容 二.我的收获(包括我完成的所有作业的链接+收获)不能只有作业链接,没有收获 作业次数 作业链接 第一次 C语言I博客作业01 第二次 C语言I博客作业02 第三次 C语言I博客作业0 ...
- lua table 的操作(四)
table在前面作过介绍,它是一种关联数组,这种关联指的是可以设置各类类型的key来存储值. 1.table 间的数据传递 -- 为 table a 并设置元素,然后将 a 赋值给 b,则 a 与 b ...
- HashMap集合-遍历方法
# HashMap集合-遍历方法 先定义好集合: public static void main(String[] args) { Map<String,String> onemap=ne ...
- 创建Vofuria工程,获取产品密钥
进入Vofuria官网 https://developer.vuforia.com/vui/develop/licenses/free/new 然后点击 然后在License Name中填写izji刚 ...
- hyper-v虚拟机centos7网络配置
原文地址:https://jingyan.baidu.com/article/91f5db1b0279bd1c7e05e377.html hyper-v安装了centos7之后并不能上网,这里简单介绍 ...
- python 基础(十五)--time和datatime模块
time模块 time.time():返回当前时间,时间戳 time.clock():返回cpu时间(?),当有time.sleep()时,time.clock()不计时 time.localtime ...
- MyEclipse的Server标签出现:Could not create the view: An unexpected exception was thrown
删除工作空间下的.metadata\.plugins\org.eclipse.core.runtime\.settings\com.genuitec.eclipse.ast.deploy.core.p ...