V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
guonaihong
V2EX  ›  Go 编程语言

新年快乐, tostruct 小库来拜年

  •  
  •   guonaihong ·
    guonaihong · 2023-01-22 12:43:06 +08:00 · 2000 次点击
    这是一个创建于 675 天前的主题,其中的信息可能已经有所发展或是发生改变。

    2023

    祝大家新年快乐,新的一年经济恢复,rmb 多多。

    github 地址

    https://github.com/antlabs/tostruct

    tostruct

    Go codecov

    json/yaml/http header/query string 转成 struct 定义,免去手写 struct 的烦恼.

    一、json 字符串生成结构体

    import (
        "github.com/antlabs/tostruct/json"
        "github.com/antlabs/tostruct/option"
    )
    
    func main() {
    	var str = `{
    	"action": "Deactivate user",
    	"entities": [
    		{
    		"uuid": "4759aa70-XXXX-XXXX-925f-6fa0510823ba",
    		"type": "user",
    		"created": 1542595573399,
    		"modified": 1542597578147,
    		"username": "user1",
    		"activated": false,
    		"nickname": "user"
    		}],
    		"timestamp": 1542602157258,
    		"duration": 12
    	}`
    
    	// 父子结构合在一起
    	all, _ := json.Marshal([]byte(str), option.WithStructName("reqName"))
    	fmt.Println(string(all))
    	/*
    	type reqName struct {
    		Action   string `json:"action"`
    		Duration int    `json:"duration"`
    		Entities []struct {
    			Activated bool   `json:"activated"`
    			Created   int    `json:"created"`
    			Modified  int    `json:"modified"`
    			Nickname  string `json:"nickname"`
    			Type      string `json:"type"`
    			Username  string `json:"username"`
    			UUID      string `json:"uuid"`
    		} `json:"entities"`
    		Timestamp int `json:"timestamp"`
    	}
    	*/
    
    	// 子结构拆分
    	all, _ := json.Marshal([]byte(str), option.WithStructName("reqName"), option.WithNotInline())
    	fmt.Println(string(all))
    	/*
    	type reqName struct {
    		Action    string     `json:"action"`
    		Duration  int        `json:"duration"`
    		Entities  []Entities `json:"entities"`
    		Timestamp int        `json:"timestamp"`
    	}
    
    	type Entities struct {
    		Activated bool   `json:"activated"`
    		Created   int    `json:"created"`
    		Modified  int    `json:"modified"`
    		Nickname  string `json:"nickname"`
    		Type      string `json:"type"`
    		Username  string `json:"username"`
    		UUID      string `json:"uuid"`
    	}
    	*/
    }
    

    二、http header 生成结构体

    import (
        "github.com/antlabs/tostruct/header"
        "github.com/antlabs/tostruct/option"
    	"net/http"
    )
    
    func main() {
    	h := http.header{
    		"bool": []string{"true"},
    		"int" : []string{"1"},
    		"string" : []string{"hello"},
    		"float64" : []string{"3.14"},
    	}
    	res, err := header.Marshal(h, option.WithStructName("test"), option.WithTagName("header"))
    	if err != nil {
    		fmt.Println(err.Error())
    		return
    	}
    
    	fmt.Println(string(res))
    	/*
    type test struct {
    	Bool    bool    `header:"bool"`
    	Float64 float64 `header:"float64"`
    	Int     int     `header:"int"`
    	String  string  `header:"string"`
    }
    	*/
    }
    

    三、查询字符串生成结构体

    import (
        "github.com/antlabs/tostruct/url"
        "github.com/antlabs/tostruct/option"
    )
    
    func main() {
    	url := "http://127.0.0.1:8080?int=1&float64=1.1&bool=true&string=hello"
    	res, err := header.Marshal(h, option.WithStructName("test"), option.WithTagName("form"))
    	if err != nil {
    		fmt.Println(err.Error())
    		return
    	}
    	fmt.Println(string(res))
    	/*
    type test struct {
    	Bool    bool    `form:"bool"`
    	Float64 float64 `form:"float64"`
    	Int     int     `form:"int"`
    	String  string  `form:"string"`
    }
    	*/
    }
    
    

    四、yaml 生成结构体

    import (
        "github.com/antlabs/tostruct/url"
        "github.com/antlabs/tostruct/option"
    	"github.com/antlabs/tostruct/yaml"
    )
    
    func main() {
    	str := `
    a: 1
    b: 3.14
    c: hello
    d:
      - aa
      - bb
    e:
      - a: 1
        b: 3.14
        c: hello
    f:
      first: 1
      second: 3.14
    `
    
    	all, err := Marshal([]byte(str), option.WithStructName("reqName"))
    	if err != nil {
    		return
    	}
    	fmt.Println(all)
    	/*
    type reqName struct {
    	A int      `yaml:"a"`
    	B float64  `yaml:"b"`
    	C string   `yaml:"c"`
    	D []string `yaml:"d"`
    	E []struct {
    		A int     `yaml:"a"`
    		B float64 `yaml:"b"`
    		C string  `yaml:"c"`
    	} `yaml:"e"`
    	F struct {
    		First  int     `yaml:"first"`
    		Second float64 `yaml:"second"`
    	} `yaml:"f"`
    }
    
    	*/
    
    	all, err := Marshal([]byte(str), option.WithStructName("reqName"), option.WithNotInline())
    	if err != nil {
    		return
    	}
    	fmt.Println(all)
    /*
    type reqName struct {
    	A int      `yaml:"a"`
    	B float64  `yaml:"b"`
    	C string   `yaml:"c"`
    	D []string `yaml:"d"`
    	E []E      `yaml:"e"`
    	F F        `yaml:"f"`
    }
    
    type E struct {
    	A int     `yaml:"a"`
    	B float64 `yaml:"b"`
    	C string  `yaml:"c"`
    }
    
    type F struct {
    	First  int     `yaml:"first"`
    	Second float64 `yaml:"second"`
    }
    */
    }
    
    10 条回复    2023-02-19 22:59:30 +08:00
    hahadaxigua834
        1
    hahadaxigua834  
       2023-01-22 13:23:24 +08:00   ❤️ 1
    提个建议哈,可以加上命令行功能,用户可以配合 gogenerate 使用而不需要再写一个程序。
    guonaihong
        2
    guonaihong  
    OP
       2023-01-22 13:53:03 +08:00
    @hahadaxigua834 这块已经在做,哈哈。。。代码在私有仓库中,过几天会开放出来。
    liaohongxing
        3
    liaohongxing  
       2023-01-22 14:00:11 +08:00   ❤️ 1
    已 star
    yougg
        4
    yougg  
       2023-01-22 14:04:36 +08:00 via Android   ❤️ 1
    建议做成在线网页版
    dw2693734d
        5
    dw2693734d  
       2023-01-22 14:30:18 +08:00
    @yougg 有了,谷歌一下
    guonaihong
        6
    guonaihong  
    OP
       2023-01-22 14:50:41 +08:00
    @yougg 我可能不做网页版的,会根据 dsl 生成 http client/codemsg/http server 之类的代码(在另一个仓库中)。这块还没有同类库。根据 json 生成结构体大部分还是服务这些需求,何不更进一步,直接生成所要代码。
    dextercai
        7
    dextercai  
       2023-01-22 20:24:38 +08:00   ❤️ 1
    很棒,已 Star ,期待命令行功能
    guonaihong
        8
    guonaihong  
    OP
       2023-01-28 22:52:29 +08:00
    PaulSamuelson
        9
    PaulSamuelson  
       2023-02-19 18:10:59 +08:00
    guonaihong
        10
    guonaihong  
    OP
       2023-02-19 22:59:30 +08:00
    @duanquanwu 很棒,规整了很多模型转换。但是,很多时候生成模型只是为了实现 http client, server, grpc ,何不更进一步,直接生成所需代码。我在 https://github.com/antlabs/h2o 库就在做这样的尝试。曾经 30 多个 http client 写配置一天生成完。可否加个微信,NzEwMzkwNTE1 。一起讨论下代码生成的话题。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5475 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 09:05 · PVG 17:05 · LAX 01:05 · JFK 04:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.