4 stable releases
1.0.4 | Nov 22, 2021 |
---|---|
1.0.3 | Nov 12, 2021 |
1.0.2 | Nov 8, 2021 |
1.0.1 | Nov 5, 2021 |
#1219 in Development tools
153 downloads per month
Used in 8 crates
(2 directly)
15KB
172 lines
Gostd
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
- Go基础类型在rust实现,在gostd::builtin 中,比如 int64 = i64, int32 = i32
- 强制转换宏,例如 2 as i64 等价 int64!(2) 跟Go的int64(2)就多个!
- time库在rust实现 gostd::time
- time库支持macOSX 和linux平台,通过libc库调用C函数实现 time::Now()
- time,支持各种格式显示时间。
- docs.rs文档增加例子程序"RUN"按钮,但是要复制代码本地运行,在rust play运行不了(因为下载量没到前100)。
- time支持local时区信息自动从系统读取,可以用time::Now()获取本地时间。
- strings模块,字符串处理函数已完成。除了Reader相关方法还没全实现。(version >=0.2.3)
- strings模块, 完成剩余的方法实现。(version >=0.2.4)
- io模块,完成部分接口例如Reader,Writer等。(version >=0.2.4)
- http模块的client客户端功能,支持http和https。(version >=0.2.6)
- 完成bytes模块。(version >=0.2.8)
- 完成mime::multipart模块。(version >=0.3.1)
- 修复windos10平台编译失败的bug。(version>=0.3.18)
独立发布包
独立发布gostd_time,代码等价于 use gostd::time 。
独立发布gostd_builtin, 代码等价于 use gostd::builtin 。
使用例子
multipart模块
form-data Body
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模块
client客户端
- POST
use gostd::net::http;
fn main() -> Result<(), std::io::Error> {
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(())
}
或者
use gostd::net::http::{Client, Method, Request};
fn main() -> Result<(), std::io::Error> {
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"}
- GET
use gostd::net::http;
fn main() -> Result<(), std::io::Error> {
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(())
}
或者
use gostd::net::http::{Client, Method, Request};
fn main() -> Result<(), std::io::Error> {
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模块
- 字符串替换 strings::ReplaceAll()
use gostd::strings;
fn main() {
assert_eq!(
"moo moo moo",
strings::ReplaceAll("oink oink oink", "oink", "moo")
);
}
- 字符串分割 strings::Split()
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"));
}
- 字符串位置查找 strings::Index
use gostd::strings;
fn main() {
assert_eq!(4, strings::Index("chicken", "ken"));
assert_eq!(-1, strings::Index("chicken", "dmr"));
}
- 将多个字符串连接成一个新字符串 strings::Join
use gostd::strings;
fn main() {
let s = vec!["foo", "bar", "baz"];
assert_eq!("foo, bar, baz", strings::Join(s, ", "));
}
- 字符串转换成大写 strings::ToUpper
use gostd::strings;
fn main() {
assert_eq!("GOPHER", strings::ToUpper("Gopher"));
}
- 字符串转换成小写 strings::ToLower
use gostd::strings;
fn main() {
assert_eq!("gopher", strings::ToLower("Gopher"));
}
lib.rs
:
Package builtin binds the basic type in go through the type alias, and implements the basic type cast macro function.