]> git.immae.eu Git - perso/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Front.git/blame - api/api.go
Add column 'status' to market_configs.
[perso/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Front.git] / api / api.go
CommitLineData
7a9e5112 1package api
2
3import (
4 "net/http"
5 "unicode"
6
7 "github.com/gin-gonic/gin"
8)
9
85545aba 10var CONFIG Config
11
12type Config struct {
13 JwtSecret string `toml:"jwt_secret"`
14 PasswordResetSecret string `toml:"password_reset_secret"`
15 FreeSMSUser string `toml:"free_sms_user"`
16 FreeSMSPass string `toml:"free_sms_pass"`
17}
18
19func SetConfig(config Config) {
20 CONFIG = config
21
22 JWT_SECRET = []byte(config.JwtSecret)
23 PASSWORD_RESET_SECRET = []byte(config.PasswordResetSecret)
24}
25
7a9e5112 26type Error struct {
27 Code ErrorCode
28 UserMessage string
29 err error
30}
31
32func (e Error) Err() error {
33 if e.err != nil {
34 return e
35 }
36
37 return nil
38}
39
40func (e Error) Error() string {
41 if e.err != nil {
42 return e.err.Error()
43 }
44
45 return ""
46}
47
24e47979 48func ErrorIs(err error, code ErrorCode) bool {
49 if err == nil {
50 return false
51 }
52
53 if apiError, ok := err.(*Error); !ok {
54 return false
55 } else {
56 return apiError.Code == code
57 }
58}
59
7a9e5112 60func NewInternalError(err error) *Error {
299b6b6d 61 if apiError, ok := err.(*Error); ok {
62 return apiError
63 }
7a9e5112 64 return &Error{InternalError, "internal error", err}
65}
66
67func ToSnake(in string) string {
68 runes := []rune(in)
69 length := len(runes)
70
71 var out []rune
72 for i := 0; i < length; i++ {
73 if i > 0 && unicode.IsUpper(runes[i]) && ((i+1 < length && unicode.IsLower(runes[i+1])) || unicode.IsLower(runes[i-1])) {
74 out = append(out, '_')
75 }
76 out = append(out, unicode.ToLower(runes[i]))
77 }
78
79 return string(out)
80}
81
82type Response struct {
83 StatusCode Status `json:"-"`
84 ErrorCode ErrorCode `json:"-"`
85
86 Status string `json:"status"`
87 Code string `json:"code,omitempty"`
88 Response interface{} `json:"response,omitempty"`
89 Message string `json:"message,omitempty"`
90}
91
92func (r Response) populateStatus() Response {
93 r.Status = ToSnake(r.StatusCode.String())
94
95 if r.ErrorCode != 0 {
96 r.Code = ToSnake(r.ErrorCode.String())
97 }
98
99 return r
100}
101
102func ErrorResponse(code ErrorCode, message string) Response {
103 return Response{
104 StatusCode: NOK,
105 ErrorCode: code,
106 Message: message,
107 }
108}
109
110func SuccessResponse(data interface{}) Response {
111 return Response{
112 StatusCode: OK,
113 Response: data,
114 }
115}
116
117func WriteJsonResponse(response Response, c *gin.Context) {
118 response = response.populateStatus()
119
120 c.JSON(StatusToHttpCode(response.StatusCode, response.ErrorCode), response)
121}
122
123func WriteBinary(contentType string, b []byte, c *gin.Context) {
124 c.Data(http.StatusOK, contentType, b)
125}
126
127type Middleware func(*gin.Context) *Error
128
129func M(handler Middleware) gin.HandlerFunc {
130 return func(c *gin.Context) {
131 err := handler(c)
132
133 if err != nil {
134 WriteJsonResponse(ErrorResponse(err.Code, err.UserMessage), c)
135 c.Error(err)
136 c.Abort()
137 } else {
138 c.Next()
139 }
140 }
141}
142
143type Query interface {
144 ValidateParams() *Error
145 Run() (interface{}, *Error)
146}
147
148func RunQuery(query Query, c *gin.Context) {
149 if err := query.ValidateParams(); err != nil {
150 WriteJsonResponse(ErrorResponse(err.Code, err.UserMessage), c)
151 c.Error(err)
152 return
153 }
154
155 if out, err := query.Run(); err != nil {
156 WriteJsonResponse(ErrorResponse(err.Code, err.UserMessage), c)
157 c.Error(err)
158 } else {
159 WriteJsonResponse(SuccessResponse(out), c)
160 }
161}