gostd 0.4.5

gostd is the go standard library implementation in rust. gostd 是Go标准库的rust实现
Documentation
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
# [Gostd]https://github.com/wandercn/gostd

[![crates.io](https://img.shields.io/crates/v/gostd.svg?color=yellow)](https://crates.io/crates/gostd)
[![Released API docs](https://docs.rs/gostd/badge.svg)](https://docs.rs/gostd)
[![GPL3 licensed](https://img.shields.io/github/license/wandercn/gostd.svg)](./LICENSE)
[![Downloads of Crates.io](https://img.shields.io/crates/d/gostd.svg)](https://crates.io/crates/gostd)
[![Lines of code](https://img.shields.io/tokei/lines/github/wandercn/gostd.svg)](#)
[![Build](https://img.shields.io/github/workflow/status/wandercn/gostd/Rust.svg)](#)
[![Languages](https://img.shields.io/github/languages/top/wandercn/gostd.svg)](#)

Gostd is the golang standard library implementation in rust-lang.

Gostd是rust-lang中的golang标准库实现。

rust 语法比go复杂,但是go代码简单好理解,想通过这个项目把go的标准库通过rust实现。以后有什么go的项目可以通过它方便翻译代码到rust,比如把 import "bytes" 改成 use gostd::bytes 就可以实现转换。

本项目纯粹个人兴趣,大概率会失败,但是梦想还是要有的万一它实现了。

go to rust,to be rust or to be failed.

# 已知难点
- go底层特性可能无法用rust实现,比如跟运行时相关的反射reflect,如果有依赖此库需要通过rust中的方式处理。
- 基础数据类型的转换,比如string是否采用自定义类型比如GoString来实现还是用string,float64(go) -> f64(rust)等等。
- 还有指针类型,幸好go的指针操作相比rust要少。
- go中的接口如何用rust的trait的实现?个人感觉还相对比较容易
- go中的不定参数在rust中只能用宏实现,这个比较麻烦,个人目前还不知道宏能不能像方法一样绑定到sturct上。

## 需要用rust实现的go标准库列表,go.1.17.1代码做参考。

go 这个包不会实现,因为我们转换成rust基本用不上这个包。
```
├── archive
├── bufio
├── builtin
├── bytes
├── cmd
├── compress
├── container
├── context
├── crypto
├── database
├── debug
├── embed
├── encoding
├── errors
├── expvar
├── flag
├── fmt
├── go
├── hash
├── html
├── image
├── index
├── internal
├── io
├── log
├── math
├── mime
├── net
├── os
├── path
├── plugin
├── reflect
├── regexp
├── runtime
├── sort
├── strconv
├── strings
├── sync
├── syscall
├── testdata
├── testing
├── text
├── time
├── unicode
├── unsafe
└── vendor
```

## 对应预期实现后的gostd的Model列表
```
use gostd::archive
use gostd::bufio
use gostd::builtin
use gostd::bytes
use gostd::cmd
use gostd::compress
use gostd::container
use gostd::context
use gostd::crypto
use gostd::database
use gostd::debug
use gostd::embed
use gostd::encoding
use gostd::errors
use gostd::expvar
use gostd::flag
use gostd::fmt
use gostd::go
use gostd::hash
use gostd::html
use gostd::image
use gostd::index
use gostd::internal
use gostd::io
use gostd::log
use gostd::math
use gostd::mime
use gostd::net
use gostd::os
use gostd::path
use gostd::plugin
use gostd::reflect
use gostd::regexp
use gostd::runtime
use gostd::sort
use gostd::strconv
use gostd::strings
use gostd::sync
use gostd::syscall
use gostd::testdata
use gostd::testing
use gostd::text
use gostd::time
use gostd::unicode
use gostd::unsafe
use gostd::vendor
```

# 大致方向

- 分析go标准库的依赖情况,从最底层的库开始实现。
- go源码中的单元测试也会一并用rust实现,这样可以保证代码的健壮性。

# todo

- [x] Go基础类型在rust实现,在gostd::builtin 中,比如 int64 = i64, int32 = i32
- [x] 强制转换宏,例如 2 as i64 等价 int64!(2) 跟Go的int64(2)就多个!
- [x] time库在rust实现 gostd::time
- [x] time库支持macOSX 和linux平台,通过libc库调用C函数实现 time::Now()
- [x] time,支持各种格式显示时间。
- [x] docs.rs文档增加例子程序"RUN"按钮,但是要复制代码本地运行,在rust play运行不了(因为下载量没到前100)。
- [x] time支持local时区信息自动从系统读取,可以用time::Now()获取本地时间。
- [x] strings模块,字符串处理函数已完成。除了Reader相关方法还没全实现。(version >=0.2.3)
- [x] strings模块, 完成剩余的方法实现。(version >=0.2.4)
- [x] io模块,完成部分接口例如Reader,Writer等。(version >=0.2.4)
- [x] http模块的client客户端功能,支持http和https。(version >=0.2.6)
- [x] 完成bytes模块。(version >=0.2.8)
- [x] 完成mime::multipart模块。(version >=0.3.1)
- [x] 修复windos10平台编译失败的bug。(version>=0.3.18)
- [x] 对net/http模块,自定义错误处理上的优化,引入bytes提高性能,api会有参数类型的变化(version>=0.4.1)
- [x] 对net/http模块,增加异步编程的支持,独立一个模块async_http支持异步编程,原来模块保持不变。(version>=0.4.3)
- [x] net::http,net::url,io,strings,unicode,bytes 独立发布包。

# 独立发布包
 
独立发布gostd_time,代码等价于 use gostd::time 。 

独立发布gostd_builtin, 代码等价于 use gostd::builtin 。 

独立发布gostd_unicode, 代码等价于 use gostd::unicode 。 

独立发布gostd_http, 代码等价于 use gostd::net::http 。 

独立发布gostd_strings, 代码等价于 use gostd::strings 。 

独立发布gostd_bytes, 代码等价于 use gostd::bytes 。 

独立发布gostd_url, 代码等价于 use gostd::net::url 。 

独立发布gostd_io, 代码等价于 use gostd::io 。 

# 使用例子

## multipart模块

### form-data Body

```rust
use gostd::bytes;
use gostd::mime::multipart::Writer;
use gostd::net::http::{Client, Method, Request};
fn main() -> Result<(), std::io::Error> {
    let mut body = bytes::Buffer::new();
    let mut w = Writer::new(&mut body);
    w.WriteField("requestId", "12121231231")?;
    w.WriteField("testTime", "2022-01-22 18:00:00")?;
    w.WriteField("checkTime", "2022-01-22 22:00:00")?;
    w.WriteField("auditTime", "2022-01-22 23:00:00")?;
    w.WriteField("tubeCode", "QCGD99SDF")?;
    w.WriteField("testRatio", "1")?;
    w.WriteField("name", "刘xxx")?;
    w.WriteField("sex", "1")?;
    w.WriteField("birthdate", "20003-07-02")?;
    w.WriteField("address", "北京市丰台区")?;
    w.WriteField("phoneNumber", "1881xxxx")?;
    w.WriteField("cardType", "身份证")?;
    w.WriteField("cardNumber", "xxxx")?;
    w.WriteField("testResult", "0")?;
    w.WriteField("testUserName", "xxx")?;
    w.WriteField("checkUserName", "xxx")?;
    w.Close()?;
    let contentType = w.FormDataContentType();
    let url = "http://www.baidu.com";
    let mut req = Request::New(Method::Post, url, Some(body.Bytes()))?;
    req.Header.Set("Content-Type", contentType.as_str());
    let mut client = Client::New();
    let response = client.Do(&mut req)?;

    println!(
        "{}",
        String::from_utf8(response.Body.expect("return body error")).unwrap()
    );

    Ok(())
}
```



## http模块

### Async 异步http
  默认不启用异步方式

    features =["async-std-rt"] // 使用async_std 异步运行时
    或者 features =["tokio-rt"] // 使用 tokio 异步运行时

#### 使用async_std

 Cargo.toml配置:

    async-std = {version = "1.13" ,features = ["attributes"]}
    gostd = { version = "0.4" ,features =["async-std-rt"]}

1. POST

```rust

use gostd::net::http::async_http 

#[async_std::main]
async fn main() -> anyhow::Result<()> {
    let url = "https://petstore.swagger.io/v2/pet";
    let postbody = r#"{"id":0,"category":{"id":0,"name":"string"},"name":"doggie","photoUrls":["string"],"tags":[{"id":0,"name":"string"}],"status":"available"}"#
   .as_bytes()
   .to_vec();
    let response = async_http::Post(url, "application/json", Some(postbody.into())).await?;

    println!(
        "{}",
        String::from_utf8(response.Body.expect("return body error").to_vec()).unwrap()
    );

    Ok(())
}

```
或者 

```rust
use gostd::net::http::{async_http::AsyncClient, Method, Request};

#[async_std::main]
async fn main() -> anyhow::Result<()> {
    let url = "https://petstore.swagger.io/v2/pet";

    let postbody = r#"{
      "id": 0,
      "category": {
        "id": 0,
        "name": "string"
      },
      "name": "doggie",
      "photoUrls": [
        "string"
      ],
      "tags": [
        {
          "id": 0,
          "name": "string"
        }
      ],
      "status": "available"
    }"#
    .as_bytes()
    .to_vec();

    let mut req = Request::New(Method::Post, url, Some(postbody.into()))?;

    req.Header.Set("accept", "application/json");
    req.Header.Set("Content-Type", "application/json");
    let mut client = AsyncClient::New();
    let response = client.Do(&mut req).await?;

    println!(
        "{}",
        String::from_utf8(response.Body.expect("return body error").to_vec()).unwrap()
    );

    Ok(())
}
// output
// {"id":92233723685477587,"category":{"id":,"name":"string"},"name":"doggie","photoUrls":["string"],"tags":[{"id":,"name":"string"}],"status":"available"}

```

2. GET

```rust
use gostd::net::http::async_http;

#[async_std::main]
async fn main() -> anyhow::Result<()> {
    let url = "https://petstore.swagger.io/v2/pet/findByStatus?status=available";
    let response = async_http::Get(url).await?;

    println!(
        "{}",
        String::from_utf8(response.Body.expect("return body error").to_vec()).unwrap()
    );

    Ok(())
}

``` 
或者 

```rust
use gostd::net::http::{async_http::AsyncClient, Method, Request};

#[async_std::main]
async fn main() -> anyhow::Result<()> {
    let url = "https://petstore.swagger.io/v2/pet/findByStatus?status=available";
    let mut req = Request::New(Method::Get, url, None)?;
    req.Header.Set("Content-Type", "application/json");

    let mut client = AsyncClient::New();

    let response = client.Do(&mut req).await?;
    println!(
        "{}",
        String::from_utf8(response.Body.expect("return body error").to_vec()).unwrap()
    );

    Ok(())
}

```

#### 使用tokio

 Cargo.toml配置:

    tokio = { version = "1.44", features = ["full"] }
    gostd = { version = "0.4" ,features =["tokio-rt""]}

1. POST

```rust

use gostd::net::http::async_http 

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let url = "https://petstore.swagger.io/v2/pet";
    let postbody = r#"{"id":0,"category":{"id":0,"name":"string"},"name":"doggie","photoUrls":["string"],"tags":[{"id":0,"name":"string"}],"status":"available"}"#
   .as_bytes()
   .to_vec();
    let response = async_http::Post(url, "application/json", Some(postbody.into())).await?;

    println!(
        "{}",
        String::from_utf8(response.Body.expect("return body error").to_vec()).unwrap()
    );

    Ok(())
}

```
或者 

```rust
use gostd::net::http::{async_http::AsyncClient, Method, Request};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let url = "https://petstore.swagger.io/v2/pet";

    let postbody = r#"{
      "id": 0,
      "category": {
        "id": 0,
        "name": "string"
      },
      "name": "doggie",
      "photoUrls": [
        "string"
      ],
      "tags": [
        {
          "id": 0,
          "name": "string"
        }
      ],
      "status": "available"
    }"#
    .as_bytes()
    .to_vec();

    let mut req = Request::New(Method::Post, url, Some(postbody.into()))?;

    req.Header.Set("accept", "application/json");
    req.Header.Set("Content-Type", "application/json");
    let mut client = AsyncClient::New();
    let response = client.Do(&mut req).await?;

    println!(
        "{}",
        String::from_utf8(response.Body.expect("return body error").to_vec()).unwrap()
    );

    Ok(())
}
// output
// {"id":92233723685477587,"category":{"id":,"name":"string"},"name":"doggie","photoUrls":["string"],"tags":[{"id":,"name":"string"}],"status":"available"}

```

2. GET

```rust
use gostd::net::http::async_http;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let url = "https://petstore.swagger.io/v2/pet/findByStatus?status=available";
    let response = async_http::Get(url).await?;

    println!(
        "{}",
        String::from_utf8(response.Body.expect("return body error").to_vec()).unwrap()
    );

    Ok(())
}

``` 
或者 

```rust
use gostd::net::http::{async_http::AsyncClient, Method, Request};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let url = "https://petstore.swagger.io/v2/pet/findByStatus?status=available";
    let mut req = Request::New(Method::Get, url, None)?;
    req.Header.Set("Content-Type", "application/json");

    let mut client = AsyncClient::New();

    let response = client.Do(&mut req).await?;
    println!(
        "{}",
        String::from_utf8(response.Body.expect("return body error").to_vec()).unwrap()
    );

    Ok(())
}

```

### Sync 同步http

### client客户端

1. POST

```rust

use gostd::net::http;
fn main() -> anyhow::Result<()> {
    let url = "https://petstore.swagger.io/v2/pet";
    let postbody = r#"{"id":0,"category":{"id":0,"name":"string"},"name":"doggie","photoUrls":["string"],"tags":[{"id":0,"name":"string"}],"status":"available"}"#
   .as_bytes()
   .to_vec();
    let response = http::Post(url, "application/json", Some(postbody))?;

    println!(
        "{}",
        String::from_utf8(response.Body.expect("return body error")).unwrap()
    );

    Ok(())
}

```
或者 

```rust
use gostd::net::http::{Client, Method, Request};

fn main() -> anyhow::Result<()> {

    let url = "https://petstore.swagger.io/v2/pet";

    let postbody = r#"{
      "id": 0,
      "category": {
        "id": 0,
        "name": "string"
      },
      "name": "doggie",
      "photoUrls": [
        "string"
      ],
      "tags": [
        {
          "id": 0,
          "name": "string"
        }
      ],
      "status": "available"
    }"#
    .as_bytes()
    .to_vec();

    let mut req = Request::New(Method::Post, url, Some(postbody))?;

    req.Header.Set("accept", "application/json");
    req.Header.Set("Content-Type", "application/json");
    let mut client = Client::New();
    let response = client.Do(&mut req)?;

    println!(
        "{}",
        String::from_utf8(response.Body.expect("return body error")).unwrap()
    );

    Ok(())
}

// output
// {"id":92233723685477587,"category":{"id":,"name":"string"},"name":"doggie","photoUrls":["string"],"tags":[{"id":,"name":"string"}],"status":"available"}

```

2. GET

```rust
use gostd::net::http;

fn main() -> anyhow::Result<()> {
    let url = "https://petstore.swagger.io/v2/pet/findByStatus?status=available";
    let response = http::Get(url)?;

    println!(
        "{}",
        String::from_utf8(response.Body.expect("return body error")).unwrap()
    );

    Ok(())
}

``` 
或者 

```rust
use gostd::net::http::{Client, Method, Request};

fn main() -> anyhow::Result<()> {

    let url = "https://petstore.swagger.io/v2/pet/findByStatus?status=available";
    let mut req = Request::New(Method::Get, url, None)?;
    req.Header.Set("Content-Type", "application/json");

    let mut client = Client::New();

    let response = client.Do(&mut req)?;
    println!(
        "{}",
        String::from_utf8(response.Body.expect("return body error")).unwrap()
    );

    Ok(())
}

```


## strings模块

1. 字符串替换 strings::ReplaceAll()

```rust
use gostd::strings;

fn main() {

    assert_eq!(
        "moo moo moo",
        strings::ReplaceAll("oink oink oink", "oink", "moo")
    );
}
```

2. 字符串分割 strings::Split()

```rust
use gostd::strings;

fn main() {

    assert_eq!(vec!["a", "b", "c"], strings::Split("a,b,c", ","));
    assert_eq!(
        vec!["", "man ", "plan ", "canal panama"],
        strings::Split("a man a plan a canal panama", "a ")
    );
    assert_eq!(
        vec!["", " ", "x", "y", "z", " ", ""],
        strings::Split(" xyz ", "")
    );
    assert_eq!(vec![""], strings::Split("", "Bernardo O'Higgins"));
}

```

3. 字符串位置查找 strings::Index

```rust
use gostd::strings;

fn main() {

    assert_eq!(4, strings::Index("chicken", "ken"));
    assert_eq!(-1, strings::Index("chicken", "dmr"));
}

```

4. 将多个字符串连接成一个新字符串 strings::Join

```rust 
use gostd::strings;

fn main() {

    let s = vec!["foo", "bar", "baz"];
    assert_eq!("foo, bar, baz", strings::Join(s, ", "));
}

```

5. 字符串转换成大写 strings::ToUpper

```rust
use gostd::strings;

fn main() {

    assert_eq!("GOPHER", strings::ToUpper("Gopher"));
}
```

6. 字符串转换成小写 strings::ToLower
```rust
use gostd::strings;

fn main() {

    assert_eq!("gopher", strings::ToLower("Gopher"));
}

```