podhmo / egoist

egoistic framework framework
0 stars 0 forks source link

generate struct #38

Closed podhmo closed 4 years ago

podhmo commented 4 years ago

refs #35 refs #46

podhmo commented 4 years ago

todo: support something like this

from __future__ import annotations
from egoist.app import App

app = App()
app.include("egoist.directives.define_struct_set")

# todo: jsoniter
# todo: other framework. (e.g. go-chi, gin, echo...)

@app.define_struct_set("egoist.generate.structkit:walk")  # type: ignore
def models__models() -> None:
    from egoist.generate.structkit import runtime, structkit
    import objects

    # TODO: custom tags: e.g. json:"xxx"  -> json:"xxx" + field:"xxx"
    # def build_tag(cls: t.Type[t.Any], row: Row):
    #     name = row[0]
    #     return '`json:"{name}"`'

    # setup_build_tag(build_tag)

    with runtime.generate(structkit, classes=[objects.Person]) as m:
        m.package("models")

if __name__ == "__main__":
    app.run()
podhmo commented 4 years ago

todo

podhmo commented 4 years ago

now

from __future__ import annotations
import typing as t
from egoist.app import App

app = App(settings={"here": __file__, "rootdir": ""})
app.include("egoist.directives.define_struct_set")

@app.define_struct_set("egoist.generators.structkit:walk")  # type: ignore
def models__models() -> None:
    from egoist.generators.structkit import runtime, structkit
    import objects

    @runtime.set_metadata_handler
    def metadata_handler(
        cls: t.Type[t.Any], *, name: str, info: t.Any, metadata: runtime.Metadata
    ) -> None:
        """with form"""
        metadata["tags"] = {"json": [name.rstrip("_")], "form": [name.rstrip("_")]}

    with runtime.generate(structkit, classes=[objects.Person]) as m:
        m.package("models")

if __name__ == "__main__":
    app.run()

and objects.py

class Person:
    name: str

code generation

$ python main.py generate
[D]     create  ./models
[F]     create  ./models/models.go

generated models/models.go

package models

import (
    "github.com/podhmo/maperr"
    "encoding/json"
)

// this file is generated by egoist.generators.structkit

type Person struct {
    Name string `json:"name" form:"name"`
}

func (p *Person) UnmarshalJSON(b []byte) error {
    var err *maperr.Error

    // loading internal data
    var inner struct {
        Name *string `json:"name"`// required
    }
    if rawErr := json.Unmarshal(b, &inner); rawErr != nil  {
        return err.AddSummary(rawErr.Error())
    }

    // binding field value and required check
    {
        if inner.Name != nil  {
            p.Name = *inner.Name
        } else  {
            err = err.Add("name", maperr.Message{Text: "required"})
        }
    }

    return err.Untyped()
}