Coder Social home page Coder Social logo

gostd's Introduction

crates.io Released API docs GPL3 licensed Downloads of Crates.io Lines of code Build Languages

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)

独立发布包

独立发布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客户端

  1. 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"}
  1. 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模块

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

fn main() {

    assert_eq!(
        "moo moo moo",
        strings::ReplaceAll("oink oink oink", "oink", "moo")
    );
}
  1. 字符串分割 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"));
}
  1. 字符串位置查找 strings::Index
use gostd::strings;

fn main() {

    assert_eq!(4, strings::Index("chicken", "ken"));
    assert_eq!(-1, strings::Index("chicken", "dmr"));
}
  1. 将多个字符串连接成一个新字符串 strings::Join
use gostd::strings;

fn main() {

    let s = vec!["foo", "bar", "baz"];
    assert_eq!("foo, bar, baz", strings::Join(s, ", "));
}
  1. 字符串转换成大写 strings::ToUpper
use gostd::strings;

fn main() {

    assert_eq!("GOPHER", strings::ToUpper("Gopher"));
}
  1. 字符串转换成小写 strings::ToLower
use gostd::strings;

fn main() {

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

gostd's People

Contributors

doraemonkeys avatar wandercn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

gostd's Issues

time.unix 时间戳不对

use gostd::time;
fn main() {
    let d = time::Date(2001, 9, 9, 1, 46, 40, 0, time::UTC.clone());
    println!("{}", d.Unix());
}

正确的应该是输出是:1000000000 ,这里错误输出了1000000512
gostd version:0.1.5

"fn string" is unsafe

pub fn string(b: &[u8]) -> String 这个函数是不安全的,要么把它定义为 unsafe 的,要么请让它返回一个 Result<String, E>,比如在那个 &[u8] 不是 utf8 编码时返回错误,Safe Rust 中没有 Go 那种打印出来可能会有乱码的字符串,String 必须是合法的 utf8。

//  据我所知这在 Safe Rust 中是做不到的
b := []byte{255, 255, 255}
fmt.Println(string(b)) // 乱码

原生类型重定义、公共方法首字母大写、用&str做错误返回我也很想吐槽,毕竟这是翻译不是抄一遍,建议还是按照 Rust 而不是 Go 的哲学和规范来吧。

或者至少正确性和安全性上不要打折吧,否则 Go 翻译成 Rust 的意义是什么呢?

absDate 函数错误

use gostd::time;
fn main() {
    let year3000 = time::Date(3000, 1, 1, 0, 0, 0, 0, time::UTC.clone());
    println!("{}", year3000);
}

m:18446744073709551595
thread 'main' panicked at 'index out of bounds: the len is 13 but the index is 18446744073709551596', /Users/apple/workspace/src/github.com/wandercn/gostd/src/time/mod.rs:2497:20
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

// 这里的m错误导致daysBefore超过索引范围
let mut m = uint!(day / 31);
println!("m:{}",m);
let end = int!(daysBefore[m + 1]);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.