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

释放双眼,带上耳机,听听看~!

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

项目实战

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

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

我们首先创建一个目录:


1
2
1cargo new btc_converter
2

我们用TDD方式来开发。

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

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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
1#[cfg(test)]
2mod tests {
3    use super::*;
4
5    #[test]
6    fn test_convert_success() {
7        match convert_btc(1.2, "BTC", "USD") {
8            Ok(_) => assert!(true),
9            Err(_) => assert!(false),
10        }
11    }
12    #[test]
13    fn test_convert_success2() {
14        match convert_btc(2.1, "BTC", "MKD") {
15            Ok(_) => assert!(true),
16            Err(_) => assert!(false),
17        }
18    }
19
20    #[test]
21    fn test_convert_error_wrong_from() {
22        match convert_btc(1.2, "wrongvalue", "USD") {
23            Ok(_) => assert!(false),
24            Err(_) => assert!(true),
25        }
26    }
27
28    #[test]
29    fn test_convert_error_wrong_to() {
30        match convert_btc(1.2, "USD", "wrongvalue") {
31            Ok(_) => assert!(false),
32            Err(_) => assert!(true),
33        }
34    }
35}
36
37

我们运行命令:


1
2
1cargo test
2

结果肯定是不通过。

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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
1const API_URL: &str = "https://apiv2.bitcoinaverage.com/convert/global";
2
3//错误信息
4#[derive(From, Display, Debug)]
5enum BtcError {
6    ApiError,
7    Reqwest(reqwest::Error),
8}
9//响应信息结构体
10#[derive(Deserialize, Debug)]
11struct BtcResponse {
12    time: String,
13    success: bool,
14    price: f64,
15}
16
17
18//价格转换,直接调用相关API
19fn convert_btc(amount: f64, from: &str, to: &str) -> Result<BtcResponse, BtcError> {
20    use BtcError::*;
21    println!("---convert_btc-----{:?},{:?}", from, to);
22    let client = reqwest::Client::new();
23    let request =
24        client
25            .get(API_URL)
26            .query(&[("from", from), ("to", to), ("amount", &amount.to_string())]);
27    let response_result: BtcResponse = request.send()?.json()?;
28
29    if !response_result.success {
30        return Err(ApiError);
31    }
32
33    return Ok(response_result);
34}
35

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

现在应该都通过 了。

当然我们要引用相关包:


1
2
3
4
5
6
7
8
9
1[dependencies]
2reqwest = "0.9.12"
3serde_derive = "1.0.89"
4serde = "1.0.89"
5serde_json = "1.0.39"
6structopt = "0.2.15"
7derive_more = "0.14.0"
8
9

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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
1#[macro_use]
2extern crate serde_derive;
3#[macro_use]
4extern crate derive_more;
5use reqwest;
6use std::process::exit;
7use structopt::StructOpt;
8
9fn main() {
10    let opt = Opt::from_args();
11
12    let response = match convert_btc(opt.amount, &opt.from, &opt.to) {
13        Ok(value) => value,
14        Err(e) => {
15            println!("A error occurred when try to get value from api");
16            if opt.verbose {
17                println!("Message: {} - Details: {:?}", e, e);
18            }
19            exit(1);
20        }
21    };
22
23    if opt.silent {
24        println!("{}", response.price);
25    } else {
26        println!("{} {}", response.price, &opt.to);
27    }
28}
29const API_URL: &str = "https://apiv2.bitcoinaverage.com/convert/global";
30//错误信息
31#[derive(From, Display, Debug)]
32enum BtcError {
33    ApiError,
34    Reqwest(reqwest::Error),
35}
36//响应信息结构体
37#[derive(Deserialize, Debug)]
38struct BtcResponse {
39    time: String,
40    success: bool,
41    price: f64,
42}
43
44#[derive(Debug, StructOpt)]
45#[structopt(
46    name = "btc_converter",
47    about = "Get value of a btc value to a currency"
48)]
49struct Opt {
50    /// Set amount to convert to a currency or from a currency
51    #[structopt(default_value = "1")]
52    amount: f64,
53    /// Set the initial currency of
54    #[structopt(short = "f", long = "from", default_value = "BTC")]
55    from: String,
56    /// Set the final currency to convert
57    #[structopt(short = "t", long = "to", default_value = "USD")]
58    to: String,
59    /// Silent information about currency result
60    #[structopt(short = "s", long = "silent")]
61    silent: bool,
62    /// Verbose errors
63    #[structopt(short = "v", long = "verbose")]
64    verbose: bool,
65}
66fn convert_btc(amount: f64, from: &str, to: &str) -> Result<BtcResponse, BtcError> {
67    use BtcError::*;
68    println!("---convert_btc-----{:?},{:?}", from, to);
69    let client = reqwest::Client::new();
70    let request =
71        client
72            .get(API_URL)
73            .query(&[("from", from), ("to", to), ("amount", &amount.to_string())]);
74    let response_result: BtcResponse = request.send()?.json()?;
75
76    if !response_result.success {
77        return Err(ApiError);
78    }
79
80    return Ok(response_result);
81}
82#[cfg(test)]
83mod tests {
84    use super::*;
85
86    #[test]
87    fn test_convert_success() {
88        match convert_btc(1.2, "BTC", "USD") {
89            Ok(_) => assert!(true),
90            Err(_) => assert!(false),
91        }
92    }
93    #[test]
94    fn test_convert_success2() {
95        match convert_btc(2.1, "BTC", "MKD") {
96            Ok(_) => assert!(true),
97            Err(_) => assert!(false),
98        }
99    }
100
101    #[test]
102    fn test_convert_error_wrong_from() {
103        match convert_btc(1.2, "wrongvalue", "USD") {
104            Ok(_) => assert!(false),
105            Err(_) => assert!(true),
106        }
107    }
108
109    #[test]
110    fn test_convert_error_wrong_to() {
111        match convert_btc(1.2, "USD", "wrongvalue") {
112            Ok(_) => assert!(false),
113            Err(_) => assert!(true),
114        }
115    }
116}
117
118

API地址:

https://apiv2.bitcoinaverage.com

以上,希望对你有用。


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

给TA打赏
共{{data.count}}人
人已打赏
安全技术

C++中引用和指针的区别

2022-1-11 12:36:11

安全运维

Step into Redis- 06 - 数据库

2021-12-11 11:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索