forked from ebhomengo/niki
1
0
Fork 0

style(niki): apply code formatting and linting (#85)

This commit is contained in:
Erfan Mohammadi 2024-07-25 03:15:04 +03:30
parent 3c0d1fe347
commit 86a962b0c9
519 changed files with 155151 additions and 8891 deletions

View File

@ -14,6 +14,7 @@ run:
skip-dirs:
- (^|/)vendor($|/)
- (^|/)test($|/)
skip-files:
- .*_test.go

View File

@ -15,7 +15,7 @@ import (
// @Success 200 {object} adminserviceparam.GetAllAgentResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerAdmin
// @Router /admins/agents [get]
// @Router /admins/agents [get].
func (h Handler) GetAllAgent(c echo.Context) error {
resp, sErr := h.adminSvc.GetAllAgent(c.Request().Context())
if sErr != nil {

View File

@ -2,12 +2,13 @@ package adminkindboxreqhandler
import (
"context"
"net/http"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
querier "git.gocasts.ir/ebhomengo/niki/pkg/query_transaction/sql"
echo "github.com/labstack/echo/v4"
"net/http"
)
// Deliver godoc
@ -53,5 +54,6 @@ func (h Handler) Deliver(c echo.Context) error {
if cErr != nil {
return echo.NewHTTPError(http.StatusInternalServerError, errmsg.ErrorMsgSomethingWentWrong)
}
return c.JSON(http.StatusOK, resp)
}

View File

@ -21,7 +21,7 @@ import (
// @Failure 422 {object} httpmsg.ErrorResponse
// @Failure 500 {string} "something went wrong"
// @Security AuthBearerAdmin
// @Router /admins/kindboxreqs/{id} [get]
// @Router /admins/kindboxreqs/{id} [get].
func (h Handler) Get(c echo.Context) error {
var req param.GetKindBoxReqRequest
if err := c.Bind(&req); err != nil {

View File

@ -1,11 +1,12 @@
package adminkindboxreqhandler
import (
"net/http"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
queryparam "git.gocasts.ir/ebhomengo/niki/pkg/query_param"
echo "github.com/labstack/echo/v4"
"net/http"
)
// GetAll godoc

View File

@ -1,11 +1,11 @@
package adminkindboxreqhandler
import (
"git.gocasts.ir/ebhomengo/niki/entity"
"git.gocasts.ir/ebhomengo/niki/pkg/claim"
"net/http"
"git.gocasts.ir/ebhomengo/niki/entity"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
"git.gocasts.ir/ebhomengo/niki/pkg/claim"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
queryparam "git.gocasts.ir/ebhomengo/niki/pkg/query_param"
"github.com/labstack/echo/v4"
@ -32,12 +32,11 @@ import (
// @Success 200 {object} param.DeliveryAwaitingGetAllResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerAdmin
// @Router /admin/kindboxreqs/awaiting-delivery [get]
// @Router /admin/kindboxreqs/awaiting-delivery [get].
func (h Handler) GetAllAwaitingDelivery(c echo.Context) error {
var req param.DeliveryAwaitingGetAllRequest
if bErr := c.Bind(&req); bErr != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}

View File

@ -18,11 +18,10 @@ import (
// @Success 200 {object} param.DeliveryAwaitingGetResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerAdmin
// @Router /admin/kindboxreqs/awaiting-delivery/{id} [get]
// @Router /admin/kindboxreqs/awaiting-delivery/{id} [get].
func (h Handler) GetAwaitingDelivery(c echo.Context) error {
var req param.DeliveryAwaitingGetRequest
if bErr := c.Bind(&req); bErr != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}

View File

@ -20,5 +20,4 @@ func (h Handler) SetRoutes(e *echo.Echo) {
r.GET("/awaiting-delivery", h.GetAllAwaitingDelivery, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqGetAwaitingDeliveryPermission))
r.PUT("/:id", h.Update, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqUpdatePermission))
r.GET("/:id", h.Get, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqGetPermission))
}

View File

@ -1,10 +1,11 @@
package adminkindboxreqhandler
import (
"net/http"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"github.com/labstack/echo/v4"
"net/http"
)
// Update godoc

View File

@ -22,7 +22,7 @@ import (
// @Failure 422 {object} httpmsg.ErrorResponse
// @Failure 500 {string} "something went wrong"
// @Security AuthBearerAdmin
// @Router /agents/kindboxes/{id} [get]
// @Router /agents/kindboxes/{id} [get].
func (h Handler) Get(c echo.Context) error {
var req param.GetKindBoxRequest
if bErr := c.Bind(&req); bErr != nil {

View File

@ -1,11 +1,11 @@
package agentkindboxhandler
import (
"git.gocasts.ir/ebhomengo/niki/entity"
"git.gocasts.ir/ebhomengo/niki/pkg/claim"
"net/http"
"git.gocasts.ir/ebhomengo/niki/entity"
param "git.gocasts.ir/ebhomengo/niki/param/agent/kind_box"
"git.gocasts.ir/ebhomengo/niki/pkg/claim"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
queryparam "git.gocasts.ir/ebhomengo/niki/pkg/query_param"
"github.com/labstack/echo/v4"
@ -35,7 +35,7 @@ import (
// @Failure 422 {object} httpmsg.ErrorResponse
// @Failure 500 {string} "something went wrong"
// @Security AuthBearerAdmin
// @Router /agents/kindboxes [get]
// @Router /agents/kindboxes [get].
func (h Handler) GetAll(c echo.Context) error {
var req param.GetAllRequest

View File

@ -1,11 +1,12 @@
package agentkindboxhandler
import (
"net/http"
param "git.gocasts.ir/ebhomengo/niki/param/agent/kind_box"
"git.gocasts.ir/ebhomengo/niki/pkg/claim"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
echo "github.com/labstack/echo/v4"
"net/http"
)
// Return godoc
@ -42,7 +43,6 @@ func (h Handler) Return(c echo.Context) error {
}
err := h.agentKindBoxSvc.Return(c.Request().Context(), req)
if err != nil {
msg, code := httpmsg.Error(err)

View File

@ -17,12 +17,11 @@ import (
// @Success 204
// @Failure 400 {string} "Bad request"
// @Security AuthBearerBenefactor
// @Router /address/{id} [delete]
// @Router /address/{id} [delete].
func (h Handler) DeleteAddress(c echo.Context) error {
var req param.DeleteAddressRequest
if bErr := echo.PathParamsBinder(c).Uint("id", &req.AddressID).BindError(); bErr != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
claims := claim.GetClaimsFromEchoContext(c)

View File

@ -19,16 +19,14 @@ import (
// @Success 204
// @Failure 400 {string} "Bad request"
// @Security AuthBearerBenefactor
// @Router /address/{id} [patch]
// @Router /address/{id} [patch].
func (h Handler) UpdateAddress(c echo.Context) error {
var req param.UpdateAddressRequest
if bErr := c.Bind(&req); bErr != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
if bErr := echo.PathParamsBinder(c).Uint("id", &req.ID).BindError(); bErr != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}

View File

@ -1,10 +1,10 @@
package benefactorkindboxhandler
import (
"git.gocasts.ir/ebhomengo/niki/pkg/claim"
"net/http"
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box"
"git.gocasts.ir/ebhomengo/niki/pkg/claim"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
queryparam "git.gocasts.ir/ebhomengo/niki/pkg/query_param"
"github.com/labstack/echo/v4"

View File

@ -1,12 +1,13 @@
package benefactorkindboxreqhandler
import (
"net/http"
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req"
"git.gocasts.ir/ebhomengo/niki/pkg/claim"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
echo "github.com/labstack/echo/v4"
"net/http"
)
// Add godoc

View File

@ -1,12 +1,13 @@
package benefactorkindboxreqhandler
import (
"net/http"
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req"
"git.gocasts.ir/ebhomengo/niki/pkg/claim"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
queryparam "git.gocasts.ir/ebhomengo/niki/pkg/query_param"
"github.com/labstack/echo/v4"
"net/http"
)
// GetAll godoc
@ -31,12 +32,11 @@ import (
// @Success 200 {object} param.GetAllResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerBenefactor
// @Router /benefactor/kindboxreqs/ [get]
// @Router /benefactor/kindboxreqs/ [get].
func (h Handler) GetAll(c echo.Context) error {
var req param.GetAllRequest
if bErr := c.Bind(&req); bErr != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}

View File

@ -1,11 +1,12 @@
package benefactorkindboxreqhandler
import (
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"git.gocasts.ir/ebhomengo/niki/pkg/claim"
"github.com/labstack/echo/v4"
"net/http"
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req"
"git.gocasts.ir/ebhomengo/niki/pkg/claim"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"github.com/labstack/echo/v4"
)
// Update godoc
@ -22,9 +23,8 @@ import (
// @Failure 422 {object} httpmsg.ErrorResponse
// @Failure 500 {string} "something went wrong"
// @Security AuthBearerBenefactor
// @Router /benefactor/kindboxreqs/{id} [put]
// @Router /benefactor/kindboxreqs/{id} [put].
func (h Handler) Update(c echo.Context) error {
var req param.KindBoxReqUpdateRequest
if bErr := c.Bind(&req); bErr != nil {
return echo.NewHTTPError(http.StatusBadRequest)

View File

@ -2,10 +2,8 @@ package httpserver
import (
"fmt"
agentkindboxservice "git.gocasts.ir/ebhomengo/niki/service/agent/kind_box"
agentkindboxvalidator "git.gocasts.ir/ebhomengo/niki/validator/agent/kind_box"
config "git.gocasts.ir/ebhomengo/niki/config"
"git.gocasts.ir/ebhomengo/niki/config"
adminhandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/admin/admin"
adminKindBoxHandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/admin/kind_box"
adminkindboxreqhandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/admin/kind_box_req"
@ -19,6 +17,7 @@ import (
adminauthorizationservice "git.gocasts.ir/ebhomengo/niki/service/admin/authorization"
adminkindboxservice "git.gocasts.ir/ebhomengo/niki/service/admin/kind_box"
adminkindboxreqservice "git.gocasts.ir/ebhomengo/niki/service/admin/kind_box_req"
agentkindboxservice "git.gocasts.ir/ebhomengo/niki/service/agent/kind_box"
authservice "git.gocasts.ir/ebhomengo/niki/service/auth"
benefactoraddressservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/address"
benefactorservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/benefactor"
@ -27,6 +26,7 @@ import (
adminvalidator "git.gocasts.ir/ebhomengo/niki/validator/admin/admin"
adminkindboxvalidator "git.gocasts.ir/ebhomengo/niki/validator/admin/kind_box"
adminkindboxreqvalidator "git.gocasts.ir/ebhomengo/niki/validator/admin/kind_box_req"
agentkindboxvalidator "git.gocasts.ir/ebhomengo/niki/validator/agent/kind_box"
benefactoraddressvalidator "git.gocasts.ir/ebhomengo/niki/validator/benefactor/address"
benefactorvalidator "git.gocasts.ir/ebhomengo/niki/validator/benefactor/benefactor"
benefactorkindboxvalidator "git.gocasts.ir/ebhomengo/niki/validator/benefactor/kind_box"
@ -109,13 +109,12 @@ func (s Server) Serve() {
}
}
func RegisterSwagger(s *echo.Echo, config config.Config) {
func RegisterSwagger(s *echo.Echo, c config.Config) {
// TODO: move this to a better place and make it more dynamic and configurable
docs.SwaggerInfo.Title = "NIKI API"
docs.SwaggerInfo.Description = "This is the API documentation for the NIKI project"
docs.SwaggerInfo.Version = "1.0.0"
// docs.SwaggerInfo.BasePath = "/api/v1"
docs.SwaggerInfo.Host = fmt.Sprintf("localhost:%d", config.HTTPServer.Port)
docs.SwaggerInfo.Host = fmt.Sprintf("localhost:%d", c.HTTPServer.Port)
s.GET("/swagger/*any", echoSwagger.WrapHandler)
}

View File

@ -42,6 +42,7 @@ func initSms(cfg config.Config) *kavenegarotp.Adapter {
func InitAdminService(cfg config.Config, db *mysql.DB) adminservice.Service {
return adminservice.New(InitAdminMysql(db), InitAdminAuthService(cfg))
}
func InitBenefactorForAdminService(db *mysql.DB) benefactorforadminservice.Service {
return benefactorforadminservice.New(InitAdminMysql(db))
}

11
main.go
View File

@ -2,6 +2,8 @@ package main
import (
"flag"
"fmt"
"git.gocasts.ir/ebhomengo/niki/adapter/redis"
"git.gocasts.ir/ebhomengo/niki/config"
httpserver "git.gocasts.ir/ebhomengo/niki/delivery/http_server"
@ -22,6 +24,7 @@ type Dependencies struct {
func parseFlags() bool {
migrateFlag := flag.Bool("migrate", false, "perform database migration")
flag.Parse()
return *migrateFlag
}
@ -32,13 +35,17 @@ func parseFlags() bool {
// @securityDefinitions.apikey AuthBearerAdmin
// @in header
// @name Authorization
// @description Type the word 'Bearer' followed by a space and Admin JWT token
// @description Type the word 'Bearer' followed by a space and Admin JWT token.
func main() {
migrate := parseFlags()
cfg := config.C()
db := initDatabase(cfg, migrate)
defer db.CloseStatements()
defer func() {
if err := db.CloseStatements(); err != nil {
fmt.Printf("Error closing statements: %v\n", err)
}
}()
redisAdapter := initRedis(cfg)
dependencies := initDependencies(cfg, redisAdapter, db)

View File

@ -1,8 +1,9 @@
package benefactorkindboxreqparam
import (
entity "git.gocasts.ir/ebhomengo/niki/entity"
"time"
entity "git.gocasts.ir/ebhomengo/niki/entity"
)
type KindBoxReqAddRequest struct {

View File

@ -7,8 +7,8 @@ import (
)
type KindBoxReqUpdateRequest struct {
KindBoxReqID uint `json:"-" param:"id" example:"1"`
BenefactorID uint `json:"-" example: "1"`
KindBoxReqID uint `json:"-" param:"id" example:"1"`
BenefactorID uint `json:"-" example:"1"`
KindBoxType entity.KindBoxType `json:"kind_box_type" example:"2"`
CountRequested uint `json:"count_requested" example:"5"`
Description string `json:"description" example:"description"`
@ -17,7 +17,4 @@ type KindBoxReqUpdateRequest struct {
DeliverAddressID uint `json:"deliver_address_id" example:"1"`
}
type KindBoxReqUpdateResponse struct {
}
type KindBoxReqUpdateResponse struct{}

View File

@ -2,12 +2,7 @@ package mysqlquerybuilder
import "fmt"
func BuildFilterQuery(filter map[string]interface{}) (string, []any) {
var (
filterQuery string
args = []any{}
)
func BuildFilterQuery(filter map[string]interface{}) (filterQuery string, args []any) {
for key, value := range filter {
filterQuery += fmt.Sprintf("AND %s = ? ", key)
args = append(args, value)

View File

@ -6,17 +6,15 @@ import (
"git.gocasts.ir/ebhomengo/niki/param"
)
func BuildGetAllQuery(baseQuery string, filter param.FilterRequest, pagination param.PaginationRequest, sort param.SortRequest) (string, []any) {
func BuildGetAllQuery(baseQuery string, filter param.FilterRequest, pagination param.PaginationRequest, sort param.SortRequest) (query string, args []any) {
filterQuery, fArgs := BuildFilterQuery(filter)
paginationQuery, pArgs := BuildPaginationQuery(pagination)
sortQuery := BuildSortQuery(sort)
args := []any{}
args = append(args, fArgs...)
args = append(args, pArgs...)
query := baseQuery
query = baseQuery
if filterQuery != "" {
query = fmt.Sprintf("%s %s", query, filterQuery)
}

View File

@ -4,6 +4,6 @@ import (
"git.gocasts.ir/ebhomengo/niki/param"
)
func BuildPaginationQuery(pagination param.PaginationRequest) (string, []any) {
func BuildPaginationQuery(pagination param.PaginationRequest) (query string, args []any) {
return "LIMIT ? OFFSET ?", []any{pagination.GetPageSize(), pagination.GetOffset()}
}

View File

@ -10,5 +10,6 @@ func BuildSortQuery(sort param.SortRequest) string {
if sort.Field == "" && sort.Direction == "" {
return ""
}
return fmt.Sprintf("ORDER BY %s %s", sort.Field, sort.Direction)
}

View File

@ -7,9 +7,9 @@ import (
"sync/atomic"
)
const (
QuerierContextKey = "querier"
)
type contextKey string
const QuerierContextKey contextKey = "querier"
type conn interface {
Commit() error
@ -22,72 +22,82 @@ type conn interface {
ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error)
}
type querier struct {
type Querier struct {
txRequested atomic.Bool
initOnce sync.Once
conn conn
}
func GetQuerierFromContextOrNew(ctx context.Context) *querier {
q, ok := ctx.Value(QuerierContextKey).(*querier)
func GetQuerierFromContextOrNew(ctx context.Context) *Querier {
q, ok := ctx.Value(QuerierContextKey).(*Querier)
if !ok {
q = &querier{
q = &Querier{
txRequested: atomic.Bool{},
initOnce: sync.Once{},
conn: nil,
}
}
return q
}
func (q *querier) Begin() *querier {
func (q *Querier) Begin() *Querier {
q.txRequested.Store(true)
return q
}
func (q *querier) Continue(ctx context.Context, conn *SqlDB) (*querier, error) {
func (q *Querier) Continue(ctx context.Context, conn *SQLDB) (*Querier, error) {
var iErr error
q.initOnce.Do(func() {
if q.txRequested.Load() {
tx, bErr := conn.BeginTx(ctx, nil)
if bErr != nil {
iErr = bErr
return
}
q.conn = &SqlTx{tx}
q.conn = &SQLTx{tx}
} else {
q.conn = conn
}
})
return q, iErr
}
func (q *querier) Commit() error {
func (q *Querier) Commit() error {
return q.conn.Commit()
}
func (q *querier) Rollback() error {
func (q *Querier) Rollback() error {
return q.conn.Rollback()
}
func (q *querier) Conn() conn {
func (q *Querier) Conn() conn {
return q.conn
}
type SqlTx struct {
type SQLTx struct {
*sql.Tx
}
func (tx *SqlTx) Begin() (*sql.Tx, error) {
return &sql.Tx{}, nil
}
func (tx *SqlTx) BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error) {
func (tx *SQLTx) Begin() (*sql.Tx, error) {
return &sql.Tx{}, nil
}
type SqlDB struct {
func (tx *SQLTx) BeginTx(_ context.Context, _ *sql.TxOptions) (*sql.Tx, error) {
return &sql.Tx{}, nil
}
type SQLDB struct {
*sql.DB
}
func (db *SqlDB) Commit() error {
func (db *SQLDB) Commit() error {
return nil
}
func (db *SqlDB) Rollback() error {
func (db *SQLDB) Rollback() error {
return nil
}

View File

@ -7,12 +7,11 @@ import (
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)
func (d *DB) DeleteBenefactorAddress(ctx context.Context, addressID uint, benefactorID uint) error {
func (d *DB) DeleteBenefactorAddress(ctx context.Context, addressID, benefactorID uint) error {
const op = "mysqladdress.DeleteBenefactorAddress"
_, err := d.conn.Conn().ExecContext(ctx, `UPDATE addresses SET deleted_at = CURRENT_TIMESTAMP WHERE id = ? AND benefactor_id = ? AND deleted_at IS NULL`, addressID, benefactorID)
if err != nil {
return richerror.New(op).WithErr(err).WithKind(richerror.KindUnexpected).WithMessage(errmsg.ErrorMsgCantDeleteAddress)
}

View File

@ -9,7 +9,7 @@ import (
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)
func (d *DB) IsExistAddressByID(ctx context.Context, addressID uint, benefactorID uint) (bool, error) {
func (d *DB) IsExistAddressByID(ctx context.Context, addressID, benefactorID uint) (bool, error) {
const op = "mysqladdress.IsExistAddressByID"
row := d.conn.Conn().QueryRowContext(ctx, `select * from addresses where id = ? and benefactor_id = ? and deleted_at is null `, addressID, benefactorID)

View File

@ -35,7 +35,7 @@ func (d *DB) GetAddressByID(ctx context.Context, id uint) (*entity.Address, erro
return &address, nil
}
func (d *DB) GetAddress(ctx context.Context, addressID uint, benefactorID uint) (entity.Address, error) {
func (d *DB) GetAddress(ctx context.Context, addressID, benefactorID uint) (entity.Address, error) {
const op = "mysqladdress.GetAddress"
row := d.conn.Conn().QueryRowContext(ctx, `select * from addresses where id = ? and benefactor_id = ? and deleted_at is null`, addressID, benefactorID)

View File

@ -13,7 +13,6 @@ func (d *DB) UpdateAddress(ctx context.Context, address entity.Address) error {
provinceID, err := d.getProvinceIDByCityID(ctx, address.CityID)
if err != nil {
return err
}
@ -22,7 +21,6 @@ func (d *DB) UpdateAddress(ctx context.Context, address entity.Address) error {
WHERE id = ? AND benefactor_id = ? AND deleted_at IS NULL`
_, uErr := d.conn.Conn().ExecContext(ctx, query, address.PostalCode, address.Address, address.Lat, address.Lon, address.Name, address.CityID, provinceID, address.ID, address.BenefactorID)
if err != nil {
return richerror.New(op).WithErr(uErr).WithMessage(errmsg.ErrorMsgCantUpdateRecord).
WithKind(richerror.KindUnexpected)
}

View File

@ -4,11 +4,12 @@ import (
"context"
"database/sql"
"errors"
"time"
"git.gocasts.ir/ebhomengo/niki/entity"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
"git.gocasts.ir/ebhomengo/niki/repository/mysql"
"time"
)
func (d *DB) IsExistBenefactorByID(ctx context.Context, id uint) (bool, error) {
@ -53,10 +54,8 @@ func scanBenefactor(scanner mysql.Scanner) (entity.Benefactor, error) {
type benefactorNullableFields struct {
firstName sql.NullString
lastName sql.NullString
address sql.NullString
description sql.NullString
email sql.NullString
city sql.NullString
genderStr sql.NullString
birthdate sql.NullTime
}

View File

@ -2,8 +2,8 @@ package mysqladmin
import (
"context"
"git.gocasts.ir/ebhomengo/niki/entity"
"git.gocasts.ir/ebhomengo/niki/entity"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)
@ -15,7 +15,6 @@ func (d DB) GetAllAgent(ctx context.Context) ([]entity.Admin, error) {
query := `SELECT id, first_name, last_name, phone_number FROM admins WHERE role = 'agent' AND status = 'active'`
rows, err := d.conn.Conn().QueryContext(ctx, query)
if err != nil {
return nil, richerror.New(op).WithErr(err).WithMessage(errmsg.ErrorMsgSomethingWentWrong).WithKind(richerror.KindUnexpected)
}
defer rows.Close()
@ -24,7 +23,6 @@ func (d DB) GetAllAgent(ctx context.Context) ([]entity.Admin, error) {
var agent entity.Admin
sErr := rows.Scan(&agent.ID, &agent.FirstName, &agent.LastName, &agent.PhoneNumber)
if err != nil {
return nil, richerror.New(op).WithErr(sErr).
WithMessage(errmsg.ErrorMsgCantScanQueryResult).WithKind(richerror.KindUnexpected)
}
@ -32,7 +30,6 @@ func (d DB) GetAllAgent(ctx context.Context) ([]entity.Admin, error) {
}
if rErr := rows.Err(); rErr != nil {
return nil, richerror.New(op).WithErr(rErr).
WithMessage(errmsg.ErrorMsgSomethingWentWrong).WithKind(richerror.KindUnexpected)
}

View File

@ -4,11 +4,12 @@ import (
"context"
"database/sql"
"errors"
"time"
"git.gocasts.ir/ebhomengo/niki/entity"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
"git.gocasts.ir/ebhomengo/niki/repository/mysql"
"time"
)
func (d *DB) GetAddressByID(ctx context.Context, id uint) (*entity.Address, error) {

View File

@ -76,10 +76,8 @@ func scanBenefactor(scanner mysql.Scanner) (entity.Benefactor, error) {
type nullableFields struct {
firstName sql.NullString
lastName sql.NullString
address sql.NullString
description sql.NullString
email sql.NullString
city sql.NullString
genderStr sql.NullString
birthdate sql.NullTime
}

View File

@ -1,89 +1,91 @@
package mysql
import (
"database/sql"
"fmt"
querier "git.gocasts.ir/ebhomengo/niki/pkg/query_transaction/sql"
"sync"
"time"
"database/sql"
"fmt"
"sync"
"time"
querier "git.gocasts.ir/ebhomengo/niki/pkg/query_transaction/sql"
)
type Config struct {
Username string `koanf:"username"`
Password string `koanf:"password"`
Port int `koanf:"port"`
Host string `koanf:"host"`
DBName string `koanf:"db_name"`
Username string `koanf:"username"`
Password string `koanf:"password"`
Port int `koanf:"port"`
Host string `koanf:"host"`
DBName string `koanf:"db_name"`
}
type DB struct {
config Config
db *querier.SqlDB
mu sync.Mutex
statements map[string]*sql.Stmt
config Config
db *querier.SQLDB
mu sync.Mutex
statements map[string]*sql.Stmt
}
func (db *DB) Conn() *querier.SqlDB {
return db.db
func (db *DB) Conn() *querier.SQLDB {
return db.db
}
// TODO: this temporary to ignore linter error (magic number).
const (
dbMaxConnLifetime = time.Minute * 3
dbMaxOpenConns = 10
dbMaxIdleConns = 10
dbMaxConnLifetime = time.Minute * 3
dbMaxOpenConns = 10
dbMaxIdleConns = 10
)
func New(config Config) *DB {
// parseTime=true changes the output type of DATE and DATETIME values to time.Time
// instead of []byte / string
// The date or datetime like 0000-00-00 00:00:00 is converted into zero value of time.Time
db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@(%s:%d)/%s?parseTime=true",
config.Username, config.Password, config.Host, config.Port, config.DBName))
if err != nil {
panic(fmt.Errorf("can't open mysql db: %w", err))
}
// parseTime=true changes the output type of DATE and DATETIME values to time.Time
// instead of []byte / string
// The date or datetime like 0000-00-00 00:00:00 is converted into zero value of time.Time
db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@(%s:%d)/%s?parseTime=true",
config.Username, config.Password, config.Host, config.Port, config.DBName))
if err != nil {
panic(fmt.Errorf("can't open mysql db: %w", err))
}
// See "Important settings" section.
db.SetConnMaxLifetime(dbMaxConnLifetime)
db.SetMaxOpenConns(dbMaxOpenConns)
db.SetMaxIdleConns(dbMaxIdleConns)
// See "Important settings" section.
db.SetConnMaxLifetime(dbMaxConnLifetime)
db.SetMaxOpenConns(dbMaxOpenConns)
db.SetMaxIdleConns(dbMaxIdleConns)
return &DB{
config: config,
db: &querier.SqlDB{DB: db},
statements: make(map[string]*sql.Stmt),
}
return &DB{
config: config,
db: &querier.SQLDB{DB: db},
statements: make(map[string]*sql.Stmt),
}
}
func (p *DB) PrepareStatement(key string, query string) (*sql.Stmt, error) {
p.mu.Lock()
defer p.mu.Unlock()
func (db *DB) PrepareStatement(key, query string) (*sql.Stmt, error) {
db.mu.Lock()
defer db.mu.Unlock()
if stmt, ok := p.statements[key]; ok {
return stmt, nil
}
if stmt, ok := db.statements[key]; ok {
return stmt, nil
}
stmt, err := p.db.Prepare(query)
if err != nil {
return nil, err
}
p.statements[key] = stmt
stmt, err := db.db.Prepare(query)
if err != nil {
return nil, err
}
db.statements[key] = stmt
return stmt, nil
return stmt, nil
}
func (p *DB) CloseStatements() error {
p.mu.Lock()
defer p.mu.Unlock()
func (db *DB) CloseStatements() error {
db.mu.Lock()
defer db.mu.Unlock()
for _, stmt := range p.statements {
err := stmt.Close()
if err != nil {
return err
}
}
for _, stmt := range db.statements {
err := stmt.Close()
if err != nil {
return err
}
}
p.statements = make(map[string]*sql.Stmt)
return nil
db.statements = make(map[string]*sql.Stmt)
return nil
}

View File

@ -3,6 +3,7 @@ package mysqlkindbox
import (
"context"
"database/sql"
"git.gocasts.ir/ebhomengo/niki/entity"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
querytransaction "git.gocasts.ir/ebhomengo/niki/pkg/query_transaction/sql"
@ -48,5 +49,6 @@ func (d DB) AddBatchKindBox(ctx context.Context, kindBoxes []entity.KindBox) err
return richerror.New(op).WithErr(aErr).
WithMessage(errmsg.ErrorMsgSomethingWentWrong).WithKind(richerror.KindUnexpected)
}
return nil
}

View File

@ -8,7 +8,7 @@ import (
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)
func (d DB) EnumerateKindBox(ctx context.Context, kindBoxID uint, amount uint) error {
func (d DB) EnumerateKindBox(ctx context.Context, kindBoxID, amount uint) error {
const op = "mysqlkindbox.EnumerateKindBox"
query := `UPDATE kind_boxes SET amount = ?, status = ? WHERE id = ?`

View File

@ -2,8 +2,8 @@ package mysqlkindbox
import (
"context"
"git.gocasts.ir/ebhomengo/niki/entity"
"git.gocasts.ir/ebhomengo/niki/entity"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)
@ -13,7 +13,6 @@ func (d DB) BenefactorKindBoxExist(ctx context.Context, benefactorID, kindBoxID
var count int
if err := d.conn.Conn().QueryRowContext(ctx, `SELECT COUNT(*) FROM kind_boxes WHERE benefactor_id = ? AND id = ?`, benefactorID, kindBoxID).Scan(&count); err != nil {
return false, richerror.New(op).WithErr(err).
WithMessage(errmsg.ErrorMsgSomethingWentWrong).WithKind(richerror.KindUnexpected)
}
@ -25,6 +24,7 @@ func (d DB) KindBoxExistForAgent(ctx context.Context, kindBoxID, agentID uint) (
const op = "mysqlkindbox.KindBoxExistForAgent"
query := `SELECT COUNT(*) FROM kind_boxes WHERE id = ? AND receiver_agent_id = ? AND status = ? AND deleted_at IS NULL`
//nolint
stmt, err := d.conn.PrepareStatement(op, query)
if err != nil {
return false, richerror.New(op).WithErr(err).
@ -45,7 +45,6 @@ func (d DB) KindBoxExist(ctx context.Context, kindBoxID uint) (bool, error) {
var count int
if err := d.conn.Conn().QueryRowContext(ctx, `SELECT COUNT(*) FROM kind_boxes WHERE id = ?`, kindBoxID).Scan(&count); err != nil {
return false, richerror.New(op).WithErr(err).
WithMessage(errmsg.ErrorMsgSomethingWentWrong).WithKind(richerror.KindUnexpected)
}

View File

@ -3,6 +3,7 @@ package mysqlkindbox
import (
"context"
"database/sql"
"errors"
"git.gocasts.ir/ebhomengo/niki/entity"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
@ -16,7 +17,7 @@ func (d DB) GetKindBox(ctx context.Context, kindBoxID uint) (entity.KindBox, err
row := d.conn.Conn().QueryRowContext(ctx, query, kindBoxID)
k, err := scanKindBox(row)
if err != nil {
if err == sql.ErrNoRows {
if errors.Is(err, sql.ErrNoRows) {
return entity.KindBox{}, richerror.New(op).WithErr(err).
WithMessage(errmsg.ErrorMsgNotFound).WithKind(richerror.KindNotFound)
}

View File

@ -4,15 +4,17 @@ import (
"context"
"database/sql"
"errors"
"git.gocasts.ir/ebhomengo/niki/entity"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)
func (d DB) GetAwaitingReturnByAgent(ctx context.Context, kindBoxID uint, agentID uint) (entity.KindBox, error) {
func (d DB) GetAwaitingReturnByAgent(ctx context.Context, kindBoxID, agentID uint) (entity.KindBox, error) {
const op = "mysqlkindbox.GetAwaitingReturnByAgent"
query := `SELECT * FROM kind_boxes WHERE id = ? AND receiver_agent_id = ? AND status = ? AND deleted_at IS NULL`
//nolint
stmt, err := d.conn.PrepareStatement(op, query)
if err != nil {
return entity.KindBox{}, richerror.New(op).WithErr(err).

View File

@ -2,9 +2,9 @@ package mysqlkindbox
import (
"context"
"git.gocasts.ir/ebhomengo/niki/entity"
"time"
"git.gocasts.ir/ebhomengo/niki/entity"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)
@ -13,6 +13,7 @@ func (d DB) ReturnKindBox(ctx context.Context, kindBoxID uint, serialNumber stri
const op = "mysqlkindbox.ReturnKindBox"
query := `update kind_boxes set serial_number = ?, status = ?, returned_at = ? where id = ?`
//nolint
stmt, err := d.conn.PrepareStatement(op, query)
if err != nil {
return richerror.New(op).WithErr(err).

View File

@ -2,7 +2,6 @@ package mysqlkindbox
import (
"database/sql"
"fmt"
"time"
"git.gocasts.ir/ebhomengo/niki/entity"
@ -51,7 +50,6 @@ func scanKindBox(scanner mysql.Scanner) (entity.KindBox, error) {
&deletedAt,
)
if err != nil {
fmt.Println(err)
return entity.KindBox{}, err
}

View File

@ -2,6 +2,7 @@ package mysqlkindboxreq
import (
"context"
"git.gocasts.ir/ebhomengo/niki/entity"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"

View File

@ -15,5 +15,6 @@ func (d DB) DeleteKindBoxReqByID(ctx context.Context, kindBoxReqID uint) error {
return richerror.New(op).WithErr(dErr).
WithMessage(errmsg.ErrorMsgSomethingWentWrong).WithKind(richerror.KindUnexpected)
}
return nil
}

View File

@ -2,11 +2,11 @@ package mysqlkindboxreq
import (
"context"
querier "git.gocasts.ir/ebhomengo/niki/pkg/query_transaction/sql"
"time"
entity "git.gocasts.ir/ebhomengo/niki/entity"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
querier "git.gocasts.ir/ebhomengo/niki/pkg/query_transaction/sql"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)
@ -23,5 +23,6 @@ func (d DB) DeliverKindBoxReq(ctx context.Context, kindBoxReqID uint) error {
return richerror.New(op).WithErr(uErr).
WithMessage(errmsg.ErrorMsgSomethingWentWrong).WithKind(richerror.KindUnexpected)
}
return nil
}

View File

@ -3,6 +3,8 @@ package mysqlkindboxreq
import (
"context"
"database/sql"
"errors"
"git.gocasts.ir/ebhomengo/niki/entity"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
querier "git.gocasts.ir/ebhomengo/niki/pkg/query_transaction/sql"
@ -32,10 +34,11 @@ func (d DB) GetKindBoxReqByID(ctx context.Context, kindBoxReqID uint) (entity.Ki
"select * from kind_box_reqs where id = ? and deleted_at is null", kindBoxReqID)
k, err := scanKindBoxReq(row)
if err != nil {
if err == sql.ErrNoRows {
if errors.Is(err, sql.ErrNoRows) {
return entity.KindBoxReq{}, richerror.New(op).WithErr(err).
WithMessage(errmsg.ErrorMsgNotFound).WithKind(richerror.KindNotFound)
}
return entity.KindBoxReq{}, richerror.New(op).WithErr(err).
WithMessage(errmsg.ErrorMsgCantScanQueryResult).WithKind(richerror.KindUnexpected)
}

View File

@ -2,11 +2,11 @@ package mysqlkindboxreq
import (
"context"
"git.gocasts.ir/ebhomengo/niki/param"
builder "git.gocasts.ir/ebhomengo/niki/pkg/query_builder/mysql"
"git.gocasts.ir/ebhomengo/niki/entity"
"git.gocasts.ir/ebhomengo/niki/param"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
builder "git.gocasts.ir/ebhomengo/niki/pkg/query_builder/mysql"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)

View File

@ -3,21 +3,21 @@ package mysqlkindboxreq
import (
"context"
"database/sql"
"errors"
"git.gocasts.ir/ebhomengo/niki/entity"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)
func (d DB) GetAwaitingDeliveryByAgent(ctx context.Context, kindBoxReqID uint, agentID uint) (entity.KindBoxReq, error) {
func (d DB) GetAwaitingDeliveryByAgent(ctx context.Context, kindBoxReqID, agentID uint) (entity.KindBoxReq, error) {
const op = "mysqlkindboxreq.GetAwaitingDeliveryByAgent"
query := `SELECT * FROM kind_box_reqs WHERE id = ? AND sender_agent_id = ? AND status = ? AND deleted_at IS NULL `
row := d.conn.Conn().QueryRowContext(ctx, query, kindBoxReqID, agentID, entity.KindBoxReqAssignedSenderAgentStatus.String())
k, err := scanKindBoxReq(row)
if err != nil {
if err == sql.ErrNoRows {
if errors.Is(err, sql.ErrNoRows) {
return entity.KindBoxReq{}, richerror.New(op).WithErr(err).
WithMessage(errmsg.ErrorMsgNotFound).WithKind(richerror.KindNotFound)
}

View File

@ -14,6 +14,7 @@ func (d DB) KindBoxRequestExist(id uint) (bool, error) {
const op = "mysqlkindboxreq.KindBoxRequestExist"
query := `select * from kind_box_reqs where id = ?`
//nolint
stmt, err := d.conn.PrepareStatement(op, query)
if err != nil {
return false, richerror.New(op).WithErr(err).

View File

@ -40,7 +40,6 @@ func scanKindBoxReq(scanner mysql.Scanner) (entity.KindBoxReq, error) {
&deletedAt,
)
if err != nil {
return entity.KindBoxReq{}, err
}

View File

@ -2,6 +2,7 @@ package mysqlrefertime
import (
"context"
"git.gocasts.ir/ebhomengo/niki/entity"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
@ -16,5 +17,6 @@ func (d DB) Get(ctx context.Context, referTimeID uint) (entity.ReferTime, error)
return entity.ReferTime{}, richerror.New(op).WithErr(err).
WithMessage(errmsg.ErrorMsgCantScanQueryResult).WithKind(richerror.KindUnexpected)
}
return r, nil
}

View File

@ -2,9 +2,10 @@ package mysqlrefertime
import (
"database/sql"
"time"
"git.gocasts.ir/ebhomengo/niki/entity"
"git.gocasts.ir/ebhomengo/niki/repository/mysql"
"time"
)
func scanReferTime(scanner mysql.Scanner) (entity.ReferTime, error) {
@ -27,5 +28,6 @@ func scanReferTime(scanner mysql.Scanner) (entity.ReferTime, error) {
return entity.ReferTime{}, err
}
referTime.Status = entity.MapToReferTimeStatus(status)
return referTime, nil
}

View File

@ -14,7 +14,6 @@ func (s Service) GetAllAgent(ctx context.Context) (param.GetAllAgentResponse, er
agents, err := s.repo.GetAllAgent(ctx)
if err != nil {
return param.GetAllAgentResponse{}, richerror.New(op).WithErr(err).WithKind(richerror.KindUnexpected)
}

View File

@ -2,6 +2,7 @@ package benefactor
import (
"context"
param "git.gocasts.ir/ebhomengo/niki/param/admin/admin"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)

View File

@ -2,6 +2,7 @@ package benefactor
import (
"context"
param "git.gocasts.ir/ebhomengo/niki/param/admin/admin"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)

View File

@ -2,6 +2,7 @@ package benefactor
import (
"context"
"git.gocasts.ir/ebhomengo/niki/entity"
param "git.gocasts.ir/ebhomengo/niki/param/admin/admin"
)
@ -10,14 +11,13 @@ type Repository interface {
IsExistBenefactorByID(ctx context.Context, id uint) (bool, error)
GetAddressByID(ctx context.Context, id uint) (*entity.Address, error)
}
type BenefactorForAdminSvc interface {
type ForAdminSvc interface {
BenefactorExistByID(ctx context.Context, request param.BenefactorExistByIDRequest) (param.BenefactorExistByIDResponse, error)
AddressExistByID(ctx context.Context, request param.GetAddressByIDRequest) (param.GetAddressByIDResponse, error)
}
type Service struct {
repo Repository
benefactorSvc BenefactorForAdminSvc
repo Repository
}
func New(repo Repository) Service {

View File

@ -2,6 +2,7 @@ package adminkindboxservice
import (
"context"
entity "git.gocasts.ir/ebhomengo/niki/entity"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
@ -31,5 +32,6 @@ func (s Service) AddBatchKindBox(ctx context.Context, req param.AddKindBoxReques
if aErr != nil {
return param.AddKindBoxResponse{}, richerror.New(op).WithErr(aErr).WithKind(richerror.KindUnexpected)
}
return param.AddKindBoxResponse{}, nil
}

View File

@ -35,5 +35,6 @@ func (s Service) Deliver(ctx context.Context, req param.DeliverKindBoxReqRequest
if dErr != nil {
return param.DeliverKindBoxReqResponse{}, richerror.New(op).WithErr(dErr).WithKind(richerror.KindUnexpected)
}
return param.DeliverKindBoxReqResponse{}, nil
}

View File

@ -13,7 +13,6 @@ func (s Service) GetAllAwaitingDelivery(ctx context.Context, req param.DeliveryA
allAwaitingKindBoxReq, total, err := s.repo.GetAllKindBoxReq(ctx, req.Filter, req.Pagination, req.Sort)
if err != nil {
return param.DeliveryAwaitingGetAllResponse{}, richerror.New(op).WithErr(err)
}

View File

@ -4,6 +4,7 @@ import (
"context"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)
func (s Service) GetAwaitingDelivery(ctx context.Context, req param.DeliveryAwaitingGetRequest) (param.DeliveryAwaitingGetResponse, error) {
@ -11,8 +12,7 @@ func (s Service) GetAwaitingDelivery(ctx context.Context, req param.DeliveryAwai
kindBoxReq, err := s.repo.GetAwaitingDeliveryByAgent(ctx, req.KindBoxReqID, req.AgentID)
if err != nil {
return param.DeliveryAwaitingGetResponse{}, err
return param.DeliveryAwaitingGetResponse{}, richerror.New(op).WithErr(err)
}
return param.DeliveryAwaitingGetResponse{

View File

@ -2,6 +2,7 @@ package adminrefertimeservice
import (
"context"
param "git.gocasts.ir/ebhomengo/niki/param/admin/refer_time"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)
@ -12,5 +13,6 @@ func (s Service) GetReferTimeByID(ctx context.Context, req param.GetReferTimeReq
if gErr != nil {
return param.GetReferTimeResponse{}, richerror.New(op).WithErr(gErr).WithKind(richerror.KindUnexpected)
}
return param.GetReferTimeResponse{ReferTime: referTime}, nil
}

View File

@ -2,6 +2,7 @@ package adminrefertimeservice
import (
"context"
"git.gocasts.ir/ebhomengo/niki/entity"
)

View File

@ -2,6 +2,7 @@ package agentkindboxservice
import (
"context"
param "git.gocasts.ir/ebhomengo/niki/param/agent/kind_box"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)

View File

@ -2,6 +2,7 @@ package agentkindboxservice
import (
"context"
paginationparam "git.gocasts.ir/ebhomengo/niki/param"
param "git.gocasts.ir/ebhomengo/niki/param/agent/kind_box"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"

View File

@ -2,6 +2,7 @@ package agentkindboxservice
import (
"context"
param "git.gocasts.ir/ebhomengo/niki/param/agent/kind_box"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)

View File

@ -2,6 +2,7 @@ package agentkindboxservice
import (
"context"
"git.gocasts.ir/ebhomengo/niki/entity"
params "git.gocasts.ir/ebhomengo/niki/param"
)

View File

@ -2,6 +2,7 @@ package benefactoraddressservice
import (
"context"
"git.gocasts.ir/ebhomengo/niki/entity"
)

View File

@ -22,7 +22,6 @@ func (s Service) Update(ctx context.Context, req param.UpdateAddressRequest) err
BenefactorID: req.BenefactorID,
})
if err != nil {
return richerror.New(op).WithErr(err)
}

View File

@ -2,10 +2,10 @@ package benefactorservice
import (
"context"
"fmt"
"git.gocasts.ir/ebhomengo/niki/entity"
benefactoreparam "git.gocasts.ir/ebhomengo/niki/param/benefactor/benefactore"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)
@ -17,8 +17,7 @@ func (s Service) LoginOrRegister(ctx context.Context, req benefactoreparam.Login
return benefactoreparam.LoginOrRegisterResponse{}, richerror.New(op).WithErr(gErr).WithKind(richerror.KindUnexpected)
}
if code == "" || code != req.VerificationCode {
fmt.Print()
//return benefactoreparam.LoginOrRegisterResponse{}, richerror.New(op).WithMessage(errmsg.ErrorMsgOtpCodeIsNotValid).WithKind(richerror.KindForbidden)
return benefactoreparam.LoginOrRegisterResponse{}, richerror.New(op).WithMessage(errmsg.ErrorMsgOtpCodeIsNotValid).WithKind(richerror.KindForbidden)
}
_, dErr := s.redisOtp.DeleteCodeByPhoneNumber(ctx, req.PhoneNumber)

View File

@ -2,6 +2,7 @@ package benefactorkindboxservice
import (
"context"
params "git.gocasts.ir/ebhomengo/niki/param"
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
@ -12,7 +13,6 @@ func (s Service) GetAll(ctx context.Context, req param.KindBoxGetAllRequest) (pa
allKindBox, total, err := s.repo.GetAllKindBox(ctx, req.Filter, req.Pagination, req.Sort)
if err != nil {
return param.KindBoxGetAllResponse{}, richerror.New(op).WithErr(err)
}

View File

@ -2,6 +2,7 @@ package benefactorkindboxreqservice
import (
"context"
"git.gocasts.ir/ebhomengo/niki/entity"
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"

View File

@ -13,5 +13,6 @@ func (s Service) Delete(ctx context.Context, req param.KindBoxReqDeleteRequest)
if dErr != nil {
return param.KindBoxReqDeleteResponse{}, richerror.New(op).WithErr(dErr).WithKind(richerror.KindUnexpected)
}
return param.KindBoxReqDeleteResponse{}, nil
}

View File

@ -2,6 +2,7 @@ package benefactorkindboxreqservice
import (
"context"
params "git.gocasts.ir/ebhomengo/niki/param"
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
@ -12,7 +13,6 @@ func (s Service) GetAll(ctx context.Context, req param.GetAllRequest) (param.Get
allKindBoxReq, total, err := s.repo.GetAllKindBoxReq(ctx, req.Filter, req.Pagination, req.Sort)
if err != nil {
return param.GetAllResponse{}, richerror.New(op).WithErr(err)
}

View File

@ -2,9 +2,9 @@ package benefactorkindboxreqservice
import (
"context"
params "git.gocasts.ir/ebhomengo/niki/param"
entity "git.gocasts.ir/ebhomengo/niki/entity"
params "git.gocasts.ir/ebhomengo/niki/param"
)
type Repository interface {

View File

@ -2,11 +2,11 @@ package adminkindboxvalidator
import (
"errors"
"git.gocasts.ir/ebhomengo/niki/validator"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
"git.gocasts.ir/ebhomengo/niki/validator"
validation "github.com/go-ozzo/ozzo-validation/v4"
)

View File

@ -3,6 +3,7 @@ package adminkindboxvalidator
import (
"context"
"fmt"
"git.gocasts.ir/ebhomengo/niki/entity"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
)

View File

@ -2,6 +2,7 @@ package adminkindboxreqvalidator
import (
"errors"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"

View File

@ -2,6 +2,7 @@ package adminkindboxreqvalidator
import (
"errors"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"

View File

@ -24,9 +24,9 @@ func (v Validator) ValidateUpdateRequest(req param.KindBoxReqUpdateRequest) (map
validation.Max(uint(MaxKindBoxReq)),
),
validation.Field(&req.CountAccepted,
validation.Min(uint(MinKindBoxReq)),
validation.Max(uint(MaxKindBoxReq)),
validation.When(req.CountRequested > 0, validation.Max(uint(req.CountRequested))),
validation.Min(MinKindBoxReq),
validation.Max(MaxKindBoxReq),
validation.When(req.CountRequested > 0, validation.Max(req.CountRequested)),
validation.By(v.checkCountAcceptedMustBeLessThanCountRequested(req.ID)),
),
validation.Field(&req.KindBoxType,

View File

@ -145,6 +145,7 @@ func (v Validator) checkCountAcceptedMustBeLessThanCountRequested(kindboxreqID u
if kindBoxReq.CountRequested < countAccepted {
return fmt.Errorf(errmsg.ErrorMsgCountAcceptedOverflow)
}
return nil
}
}
@ -178,6 +179,7 @@ func (v Validator) areFilterFieldsValid(validFilters []string) validation.RuleFu
return fmt.Errorf(errmsg.ErrorMsgFiltersAreNotValid)
}
}
return nil
}
}
@ -197,6 +199,7 @@ func (v Validator) areSortFieldsValid(validSortFields []string) validation.RuleF
if sort.Field != "" && !slices.Contains(validSortFields, sort.Field) {
return fmt.Errorf(errmsg.ErrorMsgSortFieldIsNotValid)
}
return nil
}
}
@ -215,6 +218,7 @@ func (v Validator) isReferTimeIDValid(value interface{}) error {
if resp.ReferTime.Status != entity.ReferTimeActiveStatus {
return fmt.Errorf(errmsg.ErrorMsgReferTimeIsNotActive)
}
return nil
}
@ -274,6 +278,7 @@ func (v Validator) IsSerialNumbersCountValid(kindBoxReqID uint) validation.RuleF
if len(serialNumbers) != 0 && len(serialNumbers) > int(kindBoxReq.CountAccepted) {
return fmt.Errorf(errmsg.ErrorMsgInvalidSerialNumberRange)
}
return nil
}
}

View File

@ -2,6 +2,7 @@ package agentkindboxvalidator
import (
"errors"
param "git.gocasts.ir/ebhomengo/niki/param/agent/kind_box"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"

View File

@ -2,6 +2,7 @@ package agentkindboxvalidator
import (
"errors"
param "git.gocasts.ir/ebhomengo/niki/param/agent/kind_box"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"

View File

@ -2,6 +2,7 @@ package agentkindboxvalidator
import (
"errors"
param "git.gocasts.ir/ebhomengo/niki/param/agent/kind_box"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"

View File

@ -3,6 +3,7 @@ package agentkindboxvalidator
import (
"context"
"fmt"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
)

View File

@ -55,7 +55,6 @@ func (v Validator) doesCityExist(value interface{}) error {
}
func (v Validator) doesAddressExist(benefactorID uint) validation.RuleFunc {
return func(value interface{}) error {
addressID, ok := value.(uint)
if !ok {

View File

@ -3,11 +3,11 @@ package benefactorkindboxvalidator
import (
"context"
"fmt"
params "git.gocasts.ir/ebhomengo/niki/param"
"slices"
"time"
"git.gocasts.ir/ebhomengo/niki/entity"
params "git.gocasts.ir/ebhomengo/niki/param"
refertimeparam "git.gocasts.ir/ebhomengo/niki/param/admin/refer_time"
addressparam "git.gocasts.ir/ebhomengo/niki/param/benefactor/address"
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/benefactore"
@ -121,6 +121,7 @@ func (v Validator) isReferTimeIDValid(value interface{}) error {
if resp.ReferTime.Status != entity.ReferTimeActiveStatus {
return fmt.Errorf(errmsg.ErrorMsgReferTimeIsNotActive)
}
return nil
}
@ -151,6 +152,7 @@ func (v Validator) areFilterFieldsValid(validFilters []string) validation.RuleFu
return fmt.Errorf(errmsg.ErrorMsgFiltersAreNotValid)
}
}
return nil
}
}
@ -170,6 +172,7 @@ func (v Validator) areSortFieldsValid(validSortFields []string) validation.RuleF
if sort.Field != "" && !slices.Contains(validSortFields, sort.Field) {
return fmt.Errorf(errmsg.ErrorMsgSortFieldIsNotValid)
}
return nil
}
}

View File

@ -21,8 +21,8 @@ func (v Validator) ValidateUpdateRequest(req param.KindBoxReqUpdateRequest) (map
),
validation.Field(&req.CountRequested,
validation.Required,
validation.Min(uint(MinKindBoxReq)),
validation.Max(uint(MaxKindBoxReq)),
validation.Min(MinKindBoxReq),
validation.Max(MaxKindBoxReq),
),
validation.Field(&req.KindBoxType,
validation.Required,
@ -40,7 +40,6 @@ func (v Validator) ValidateUpdateRequest(req param.KindBoxReqUpdateRequest) (map
validation.Required,
validation.By(v.isReferTimeIDValid),
),
); err != nil {
fieldErrors := make(map[string]string)

View File

@ -2,13 +2,13 @@ package benefactorkindboxreqvalidator
import (
"context"
"errors"
"fmt"
params "git.gocasts.ir/ebhomengo/niki/param"
"slices"
"time"
"errors"
"git.gocasts.ir/ebhomengo/niki/entity"
params "git.gocasts.ir/ebhomengo/niki/param"
refertimeparam "git.gocasts.ir/ebhomengo/niki/param/admin/refer_time"
addressparam "git.gocasts.ir/ebhomengo/niki/param/benefactor/address"
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/benefactore"
@ -136,6 +136,7 @@ func (v Validator) isReferTimeIDValid(value interface{}) error {
if resp.ReferTime.Status != entity.ReferTimeActiveStatus {
return fmt.Errorf(errmsg.ErrorMsgReferTimeIsNotActive)
}
return nil
}
@ -152,6 +153,7 @@ func (v Validator) doesKindBoxBelongToBenefactor(benefactorID uint) validation.R
if kindBoxReq.BenefactorID != benefactorID {
return fmt.Errorf(errmsg.ErrorMsgKindBoxReqDoesntBelongToBenefactor)
}
return nil
}
}
@ -168,6 +170,7 @@ func (v Validator) doesKindBoxRequestHavePendingStatus(value interface{}) error
if kindBoxReq.Status != entity.KindBoxReqPendingStatus {
return fmt.Errorf(errmsg.ErrorMsgInvalidStatus)
}
return nil
}
@ -182,6 +185,7 @@ func (v Validator) areFilterFieldsValid(validFilters []string) validation.RuleFu
return fmt.Errorf(errmsg.ErrorMsgFiltersAreNotValid)
}
}
return nil
}
}
@ -201,6 +205,7 @@ func (v Validator) areSortFieldsValid(validSortFields []string) validation.RuleF
if sort.Field != "" && !slices.Contains(validSortFields, sort.Field) {
return fmt.Errorf(errmsg.ErrorMsgSortFieldIsNotValid)
}
return nil
}
}

View File

@ -2,10 +2,11 @@ package validator
import (
"fmt"
"slices"
params "git.gocasts.ir/ebhomengo/niki/param"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
validation "github.com/go-ozzo/ozzo-validation/v4"
"slices"
)
func AreFilterFieldsValid(validFilters []string) validation.RuleFunc {
@ -19,6 +20,7 @@ func AreFilterFieldsValid(validFilters []string) validation.RuleFunc {
return fmt.Errorf(errmsg.ErrorMsgFiltersAreNotValid)
}
}
return nil
}
}

View File

@ -2,10 +2,11 @@ package validator
import (
"fmt"
"slices"
params "git.gocasts.ir/ebhomengo/niki/param"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
validation "github.com/go-ozzo/ozzo-validation/v4"
"slices"
)
func AreSortFieldsValid(validSortFields []string) validation.RuleFunc {
@ -23,6 +24,7 @@ func AreSortFieldsValid(validSortFields []string) validation.RuleFunc {
if sort.Field != "" && !slices.Contains(validSortFields, sort.Field) {
return fmt.Errorf(errmsg.ErrorMsgSortFieldIsNotValid)
}
return nil
}
}

View File

@ -1,29 +1,55 @@
// Package depth provides the ability to traverse and retrieve Go source code dependencies in the form of
// internal and external packages.
//
// For example, the dependencies of the stdlib `strings` package can be resolved like so:
//
// import "github.com/KyleBanks/depth"
//
// var t depth.Tree
// err := t.Resolve("strings")
// if err != nil {
// log.Fatal(err)
// }
//
// // Output: "strings has 4 dependencies."
// log.Printf("%v has %v dependencies.", t.Root.Name, len(t.Root.Deps))
//
// For additional customization, simply set the appropriate flags on the `Tree` before resolving:
//
// import "github.com/KyleBanks/depth"
//
// t := depth.Tree {
// ResolveInternal: true,
// ResolveTest: true,
// MaxDepth: 10,
// }
// err := t.Resolve("strings")
package depth
import (
@ -33,22 +59,29 @@ import (
)
// ErrRootPkgNotResolved is returned when the root Pkg of the Tree cannot be resolved,
// typically because it does not exist.
var ErrRootPkgNotResolved = errors.New("unable to resolve root package")
// Importer defines a type that can import a package and return its details.
type Importer interface {
Import(name, srcDir string, im build.ImportMode) (*build.Package, error)
}
// Tree represents the top level of a Pkg and the configuration used to
// initialize and represent its contents.
type Tree struct {
Root *Pkg
ResolveInternal bool
ResolveTest bool
MaxDepth int
ResolveTest bool
MaxDepth int
Importer Importer
@ -56,74 +89,122 @@ type Tree struct {
}
// Resolve recursively finds all dependencies for the root Pkg name provided,
// and the packages it depends on.
func (t *Tree) Resolve(name string) error {
pwd, err := os.Getwd()
if err != nil {
return err
}
t.Root = &Pkg{
Name: name,
Tree: t,
Name: name,
Tree: t,
SrcDir: pwd,
Test: false,
Test: false,
}
// Reset the import cache each time to ensure a reused Tree doesn't
// reuse the same cache.
t.importCache = nil
// Allow custom importers, but use build.Default if none is provided.
if t.Importer == nil {
t.Importer = &build.Default
}
t.Root.Resolve(t.Importer)
if !t.Root.Resolved {
return ErrRootPkgNotResolved
}
return nil
}
// shouldResolveInternal determines if internal packages should be further resolved beyond the
// current parent.
//
// For example, if the parent Pkg is `github.com/foo/bar` and true is returned, all the
// internal dependencies it relies on will be resolved. If for example `strings` is one of those
// dependencies, and it is passed as the parent here, false may be returned and its internal
// dependencies will not be resolved.
func (t *Tree) shouldResolveInternal(parent *Pkg) bool {
if t.ResolveInternal {
return true
}
return parent == t.Root
}
// isAtMaxDepth returns true when the depth of the Pkg provided is at or beyond the maximum
// depth allowed by the tree.
//
// If the Tree has a MaxDepth of zero, true is never returned.
func (t *Tree) isAtMaxDepth(p *Pkg) bool {
if t.MaxDepth == 0 {
return false
}
return p.depth() >= t.MaxDepth
}
// hasSeenImport returns true if the import name provided has already been seen within the tree.
// This function only returns false for a name once.
func (t *Tree) hasSeenImport(name string) bool {
if t.importCache == nil {
t.importCache = make(map[string]struct{})
}
if _, ok := t.importCache[name]; ok {
return true
}
t.importCache[name] = struct{}{}
return false
}

View File

@ -9,176 +9,280 @@ import (
)
// Pkg represents a Go source package, and its dependencies.
type Pkg struct {
Name string `json:"name"`
Name string `json:"name"`
SrcDir string `json:"-"`
Internal bool `json:"internal"`
Resolved bool `json:"resolved"`
Test bool `json:"-"`
Tree *Tree `json:"-"`
Parent *Pkg `json:"-"`
Deps []Pkg `json:"deps"`
Resolved bool `json:"resolved"`
Test bool `json:"-"`
Tree *Tree `json:"-"`
Parent *Pkg `json:"-"`
Deps []Pkg `json:"deps"`
Raw *build.Package `json:"-"`
}
// Resolve recursively finds all dependencies for the Pkg and the packages it depends on.
func (p *Pkg) Resolve(i Importer) {
// Resolved is always true, regardless of if we skip the import,
// it is only false if there is an error while importing.
p.Resolved = true
name := p.cleanName()
if name == "" {
return
}
// Stop resolving imports if we've reached max depth or found a duplicate.
var importMode build.ImportMode
if p.Tree.hasSeenImport(name) || p.Tree.isAtMaxDepth(p) {
importMode = build.FindOnly
}
pkg, err := i.Import(name, p.SrcDir, importMode)
if err != nil {
// TODO: Check the error type?
p.Resolved = false
return
}
p.Raw = pkg
// Update the name with the fully qualified import path.
p.Name = pkg.ImportPath
// If this is an internal dependency, we may need to skip it.
if pkg.Goroot {
p.Internal = true
if !p.Tree.shouldResolveInternal(p) {
return
}
}
//first we set the regular dependencies, then we add the test dependencies
//sharing the same set. This allows us to mark all test-only deps linearly
unique := make(map[string]struct{})
p.setDeps(i, pkg.Imports, pkg.Dir, unique, false)
if p.Tree.ResolveTest {
p.setDeps(i, append(pkg.TestImports, pkg.XTestImports...), pkg.Dir, unique, true)
}
}
// setDeps takes a slice of import paths and the source directory they are relative to,
// and creates the Deps of the Pkg. Each dependency is also further resolved prior to being added
// to the Pkg.
func (p *Pkg) setDeps(i Importer, imports []string, srcDir string, unique map[string]struct{}, isTest bool) {
for _, imp := range imports {
// Mostly for testing files where cyclic imports are allowed.
if imp == p.Name {
continue
}
// Skip duplicates.
if _, ok := unique[imp]; ok {
continue
}
unique[imp] = struct{}{}
p.addDep(i, imp, srcDir, isTest)
}
sort.Sort(byInternalAndName(p.Deps))
}
// addDep creates a Pkg and it's dependencies from an imported package name.
func (p *Pkg) addDep(i Importer, name string, srcDir string, isTest bool) {
dep := Pkg{
Name: name,
Name: name,
SrcDir: srcDir,
Tree: p.Tree,
Tree: p.Tree,
Parent: p,
Test: isTest,
Test: isTest,
}
dep.Resolve(i)
p.Deps = append(p.Deps, dep)
}
// isParent goes recursively up the chain of Pkgs to determine if the name provided is ever a
// parent of the current Pkg.
func (p *Pkg) isParent(name string) bool {
if p.Parent == nil {
return false
}
if p.Parent.Name == name {
return true
}
return p.Parent.isParent(name)
}
// depth returns the depth of the Pkg within the Tree.
func (p *Pkg) depth() int {
if p.Parent == nil {
return 0
}
return p.Parent.depth() + 1
}
// cleanName returns a cleaned version of the Pkg name used for resolving dependencies.
//
// If an empty string is returned, dependencies should not be resolved.
func (p *Pkg) cleanName() string {
name := p.Name
// C 'package' cannot be resolved.
if name == "C" {
return ""
}
// Internal golang_org/* packages must be prefixed with vendor/
//
// Thanks to @davecheney for this:
// https://github.com/davecheney/graphpkg/blob/master/main.go#L46
if strings.HasPrefix(name, "golang_org") {
name = path.Join("vendor", name)
}
return name
}
// String returns a string representation of the Pkg containing the Pkg name and status.
func (p *Pkg) String() string {
b := bytes.NewBufferString(p.Name)
if !p.Resolved {
b.Write([]byte(" (unresolved)"))
}
return b.String()
}
// byInternalAndName ensures a slice of Pkgs are sorted such that the internal stdlib
// packages are always above external packages (ie. github.com/whatever).
type byInternalAndName []Pkg
func (b byInternalAndName) Len() int {
return len(b)
}
func (b byInternalAndName) Swap(i, j int) {
b[i], b[j] = b[j], b[i]
}
func (b byInternalAndName) Less(i, j int) bool {
if b[i].Internal && !b[j].Internal {
return true
} else if !b[i].Internal && b[j].Internal {
return false
}
return b[i].Name < b[j].Name
}

View File

@ -8,57 +8,99 @@ import (
)
// ToString convert the input to a string.
func ToString(obj interface{}) string {
res := fmt.Sprintf("%v", obj)
return string(res)
}
// ToJSON convert the input to a valid JSON string
func ToJSON(obj interface{}) (string, error) {
res, err := json.Marshal(obj)
if err != nil {
res = []byte("")
}
return string(res), err
}
// ToFloat convert the input string to a float, or 0.0 if the input is not a float.
func ToFloat(str string) (float64, error) {
res, err := strconv.ParseFloat(str, 64)
if err != nil {
res = 0.0
}
return res, err
}
// ToInt convert the input string or any int type to an integer type 64, or 0 if the input is not an integer.
func ToInt(value interface{}) (res int64, err error) {
val := reflect.ValueOf(value)
switch value.(type) {
case int, int8, int16, int32, int64:
res = val.Int()
case uint, uint8, uint16, uint32, uint64:
res = int64(val.Uint())
case string:
if IsInt(val.String()) {
res, err = strconv.ParseInt(val.String(), 0, 64)
if err != nil {
res = 0
}
} else {
err = fmt.Errorf("math: square root of negative number %g", value)
res = 0
}
default:
err = fmt.Errorf("math: square root of negative number %g", value)
res = 0
}
return
}
// ToBoolean convert the input string to a boolean.
func ToBoolean(str string) (bool, error) {
return strconv.ParseBool(str)
}

View File

@ -6,92 +6,155 @@ import (
)
// Abs returns absolute value of number
func Abs(value float64) float64 {
return math.Abs(value)
}
// Sign returns signum of number: 1 in case of value > 0, -1 in case of value < 0, 0 otherwise
func Sign(value float64) float64 {
if value > 0 {
return 1
} else if value < 0 {
return -1
} else {
return 0
}
}
// IsNegative returns true if value < 0
func IsNegative(value float64) bool {
return value < 0
}
// IsPositive returns true if value > 0
func IsPositive(value float64) bool {
return value > 0
}
// IsNonNegative returns true if value >= 0
func IsNonNegative(value float64) bool {
return value >= 0
}
// IsNonPositive returns true if value <= 0
func IsNonPositive(value float64) bool {
return value <= 0
}
// InRange returns true if value lies between left and right border
func InRangeInt(value, left, right interface{}) bool {
value64, _ := ToInt(value)
left64, _ := ToInt(left)
right64, _ := ToInt(right)
if left64 > right64 {
left64, right64 = right64, left64
}
return value64 >= left64 && value64 <= right64
}
// InRange returns true if value lies between left and right border
func InRangeFloat32(value, left, right float32) bool {
if left > right {
left, right = right, left
}
return value >= left && value <= right
}
// InRange returns true if value lies between left and right border
func InRangeFloat64(value, left, right float64) bool {
if left > right {
left, right = right, left
}
return value >= left && value <= right
}
// InRange returns true if value lies between left and right border, generic type to handle int, float32 or float64, all types must the same type
func InRange(value interface{}, left interface{}, right interface{}) bool {
reflectValue := reflect.TypeOf(value).Kind()
reflectLeft := reflect.TypeOf(left).Kind()
reflectRight := reflect.TypeOf(right).Kind()
if reflectValue == reflect.Int && reflectLeft == reflect.Int && reflectRight == reflect.Int {
return InRangeInt(value.(int), left.(int), right.(int))
} else if reflectValue == reflect.Float32 && reflectLeft == reflect.Float32 && reflectRight == reflect.Float32 {
return InRangeFloat32(value.(float32), left.(float32), right.(float32))
} else if reflectValue == reflect.Float64 && reflectLeft == reflect.Float64 && reflectRight == reflect.Float64 {
return InRangeFloat64(value.(float64), left.(float64), right.(float64))
} else {
return false
}
}
// IsWhole returns true if value is whole number
func IsWhole(value float64) bool {
return math.Remainder(value, 1) == 0
}
// IsNatural returns true if value is natural number (positive and whole)
func IsNatural(value float64) bool {
return IsWhole(value) && IsPositive(value)
}

File diff suppressed because it is too large Load Diff

View File

@ -13,225 +13,393 @@ import (
)
// Contains checks if the string contains the substring.
func Contains(str, substring string) bool {
return strings.Contains(str, substring)
}
// Matches checks if string matches the pattern (pattern is regular expression)
// In case of error return false
func Matches(str, pattern string) bool {
match, _ := regexp.MatchString(pattern, str)
return match
}
// LeftTrim trims characters from the left side of the input.
// If second argument is empty, it will remove leading spaces.
func LeftTrim(str, chars string) string {
if chars == "" {
return strings.TrimLeftFunc(str, unicode.IsSpace)
}
r, _ := regexp.Compile("^[" + chars + "]+")
return r.ReplaceAllString(str, "")
}
// RightTrim trims characters from the right side of the input.
// If second argument is empty, it will remove trailing spaces.
func RightTrim(str, chars string) string {
if chars == "" {
return strings.TrimRightFunc(str, unicode.IsSpace)
}
r, _ := regexp.Compile("[" + chars + "]+$")
return r.ReplaceAllString(str, "")
}
// Trim trims characters from both sides of the input.
// If second argument is empty, it will remove spaces.
func Trim(str, chars string) string {
return LeftTrim(RightTrim(str, chars), chars)
}
// WhiteList removes characters that do not appear in the whitelist.
func WhiteList(str, chars string) string {
pattern := "[^" + chars + "]+"
r, _ := regexp.Compile(pattern)
return r.ReplaceAllString(str, "")
}
// BlackList removes characters that appear in the blacklist.
func BlackList(str, chars string) string {
pattern := "[" + chars + "]+"
r, _ := regexp.Compile(pattern)
return r.ReplaceAllString(str, "")
}
// StripLow removes characters with a numerical value < 32 and 127, mostly control characters.
// If keep_new_lines is true, newline characters are preserved (\n and \r, hex 0xA and 0xD).
func StripLow(str string, keepNewLines bool) string {
chars := ""
if keepNewLines {
chars = "\x00-\x09\x0B\x0C\x0E-\x1F\x7F"
} else {
chars = "\x00-\x1F\x7F"
}
return BlackList(str, chars)
}
// ReplacePattern replaces regular expression pattern in string
func ReplacePattern(str, pattern, replace string) string {
r, _ := regexp.Compile(pattern)
return r.ReplaceAllString(str, replace)
}
// Escape replaces <, >, & and " with HTML entities.
var Escape = html.EscapeString
func addSegment(inrune, segment []rune) []rune {
if len(segment) == 0 {
return inrune
}
if len(inrune) != 0 {
inrune = append(inrune, '_')
}
inrune = append(inrune, segment...)
return inrune
}
// UnderscoreToCamelCase converts from underscore separated form to camel case form.
// Ex.: my_func => MyFunc
func UnderscoreToCamelCase(s string) string {
return strings.Replace(strings.Title(strings.Replace(strings.ToLower(s), "_", " ", -1)), " ", "", -1)
}
// CamelCaseToUnderscore converts from camel case form to underscore separated form.
// Ex.: MyFunc => my_func
func CamelCaseToUnderscore(str string) string {
var output []rune
var segment []rune
for _, r := range str {
// not treat number as separate segment
if !unicode.IsLower(r) && string(r) != "_" && !unicode.IsNumber(r) {
output = addSegment(output, segment)
segment = nil
}
segment = append(segment, unicode.ToLower(r))
}
output = addSegment(output, segment)
return string(output)
}
// Reverse returns reversed string
func Reverse(s string) string {
r := []rune(s)
for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 {
r[i], r[j] = r[j], r[i]
}
return string(r)
}
// GetLines splits string by "\n" and return array of lines
func GetLines(s string) []string {
return strings.Split(s, "\n")
}
// GetLine returns specified line of multiline string
func GetLine(s string, index int) (string, error) {
lines := GetLines(s)
if index < 0 || index >= len(lines) {
return "", errors.New("line index out of bounds")
}
return lines[index], nil
}
// RemoveTags removes all tags from HTML string
func RemoveTags(s string) string {
return ReplacePattern(s, "<[^>]*>", "")
}
// SafeFileName returns safe string that can be used in file names
func SafeFileName(str string) string {
name := strings.ToLower(str)
name = path.Clean(path.Base(name))
name = strings.Trim(name, " ")
separators, err := regexp.Compile(`[ &_=+:]`)
if err == nil {
name = separators.ReplaceAllString(name, "-")
}
legal, err := regexp.Compile(`[^[:alnum:]-.]`)
if err == nil {
name = legal.ReplaceAllString(name, "")
}
for strings.Contains(name, "--") {
name = strings.Replace(name, "--", "-", -1)
}
return name
}
// NormalizeEmail canonicalize an email address.
// The local part of the email address is lowercased for all domains; the hostname is always lowercased and
// the local part of the email address is always lowercased for hosts that are known to be case-insensitive (currently only GMail).
// Normalization follows special rules for known providers: currently, GMail addresses have dots removed in the local part and
// are stripped of tags (e.g. some.one+tag@gmail.com becomes someone@gmail.com) and all @googlemail.com addresses are
// normalized to @gmail.com.
func NormalizeEmail(str string) (string, error) {
if !IsEmail(str) {
return "", fmt.Errorf("%s is not an email", str)
}
parts := strings.Split(str, "@")
parts[0] = strings.ToLower(parts[0])
parts[1] = strings.ToLower(parts[1])
if parts[1] == "gmail.com" || parts[1] == "googlemail.com" {
parts[1] = "gmail.com"
parts[0] = strings.Split(ReplacePattern(parts[0], `\.`, ""), "+")[0]
}
return strings.Join(parts, "@"), nil
}
// Truncate a string to the closest length without breaking words.
func Truncate(str string, length int, ending string) string {
var aftstr, befstr string
if len(str) > length {
words := strings.Fields(str)
before, present := 0, 0
for i := range words {
befstr = aftstr
before = present
aftstr = aftstr + words[i] + " "
present = len(aftstr)
if present > length && i != 0 {
if (length - before) < (present - length) {
return Trim(befstr, " /\\.,\"'#!?&@+-") + ending
}
return Trim(aftstr, " /\\.,\"'#!?&@+-") + ending
}
}
}
return str
}
// PadLeft pads left side of a string if size of string is less then indicated pad length
func PadLeft(str string, padStr string, padLen int) string {
return buildPadStr(str, padStr, padLen, true, false)
}
// PadRight pads right side of a string if size of string is less then indicated pad length
func PadRight(str string, padStr string, padLen int) string {
return buildPadStr(str, padStr, padLen, false, true)
}
// PadBoth pads both sides of a string if size of string is less then indicated pad length
func PadBoth(str string, padStr string, padLen int) string {
return buildPadStr(str, padStr, padLen, true, true)
}
// PadString either left, right or both sides.
// Note that padding string can be unicode and more then one character
func buildPadStr(str string, padStr string, padLen int, padLeft bool, padRight bool) string {
// When padded length is less then the current string size
if padLen < utf8.RuneCountInString(str) {
return str
}
padLen -= utf8.RuneCountInString(str)
@ -239,32 +407,49 @@ func buildPadStr(str string, padStr string, padLen int, padLeft bool, padRight b
targetLen := padLen
targetLenLeft := targetLen
targetLenRight := targetLen
if padLeft && padRight {
targetLenLeft = padLen / 2
targetLenRight = padLen - targetLenLeft
}
strToRepeatLen := utf8.RuneCountInString(padStr)
repeatTimes := int(math.Ceil(float64(targetLen) / float64(strToRepeatLen)))
repeatedString := strings.Repeat(padStr, repeatTimes)
leftSide := ""
if padLeft {
leftSide = repeatedString[0:targetLenLeft]
}
rightSide := ""
if padRight {
rightSide = repeatedString[0:targetLenRight]
}
return leftSide + str + rightSide
}
// TruncatingErrorf removes extra args from fmt.Errorf if not formatted in the str object
func TruncatingErrorf(str string, args ...interface{}) error {
n := strings.Count(str, "%s")
return fmt.Errorf(str, args[:n]...)
}

File diff suppressed because it is too large Load Diff

View File

@ -7,415 +7,662 @@ import (
)
// AddressInfo is a struct full of address information
type AddressInfo struct {
Address string `json:"address" xml:"address"`
Street string `json:"street" xml:"street"`
City string `json:"city" xml:"city"`
State string `json:"state" xml:"state"`
Zip string `json:"zip" xml:"zip"`
Country string `json:"country" xml:"country"`
Latitude float64 `json:"latitude" xml:"latitude"`
Address string `json:"address" xml:"address"`
Street string `json:"street" xml:"street"`
City string `json:"city" xml:"city"`
State string `json:"state" xml:"state"`
Zip string `json:"zip" xml:"zip"`
Country string `json:"country" xml:"country"`
Latitude float64 `json:"latitude" xml:"latitude"`
Longitude float64 `json:"longitude" xml:"longitude"`
}
// Address will generate a struct of address information
func Address() *AddressInfo { return address(globalFaker.Rand) }
// Address will generate a struct of address information
func (f *Faker) Address() *AddressInfo { return address(f.Rand) }
func address(r *rand.Rand) *AddressInfo {
street := street(r)
city := city(r)
state := state(r)
zip := zip(r)
return &AddressInfo{
Address: street + ", " + city + ", " + state + " " + zip,
Street: street,
City: city,
State: state,
Zip: zip,
Country: country(r),
Latitude: latitude(r),
Address: street + ", " + city + ", " + state + " " + zip,
Street: street,
City: city,
State: state,
Zip: zip,
Country: country(r),
Latitude: latitude(r),
Longitude: longitude(r),
}
}
// Street will generate a random address street string
func Street() string { return street(globalFaker.Rand) }
// Street will generate a random address street string
func (f *Faker) Street() string { return street(f.Rand) }
func street(r *rand.Rand) string {
var street = ""
switch randInt := randIntRange(r, 1, 2); randInt {
case 1:
street = streetNumber(r) + " " + streetPrefix(r) + " " + streetName(r) + streetSuffix(r)
case 2:
street = streetNumber(r) + " " + streetName(r) + streetSuffix(r)
}
return street
}
// StreetNumber will generate a random address street number string
func StreetNumber() string { return streetNumber(globalFaker.Rand) }
// StreetNumber will generate a random address street number string
func (f *Faker) StreetNumber() string { return streetNumber(f.Rand) }
func streetNumber(r *rand.Rand) string {
return strings.TrimLeft(replaceWithNumbers(r, getRandValue(r, []string{"address", "number"})), "0")
}
// StreetPrefix will generate a random address street prefix string
func StreetPrefix() string { return streetPrefix(globalFaker.Rand) }
// StreetPrefix will generate a random address street prefix string
func (f *Faker) StreetPrefix() string { return streetPrefix(f.Rand) }
func streetPrefix(r *rand.Rand) string { return getRandValue(r, []string{"address", "street_prefix"}) }
// StreetName will generate a random address street name string
func StreetName() string { return streetName(globalFaker.Rand) }
// StreetName will generate a random address street name string
func (f *Faker) StreetName() string { return streetName(f.Rand) }
func streetName(r *rand.Rand) string { return getRandValue(r, []string{"address", "street_name"}) }
// StreetSuffix will generate a random address street suffix string
func StreetSuffix() string { return streetSuffix(globalFaker.Rand) }
// StreetSuffix will generate a random address street suffix string
func (f *Faker) StreetSuffix() string { return streetSuffix(f.Rand) }
func streetSuffix(r *rand.Rand) string { return getRandValue(r, []string{"address", "street_suffix"}) }
// City will generate a random city string
func City() string { return city(globalFaker.Rand) }
// City will generate a random city string
func (f *Faker) City() string { return city(f.Rand) }
func city(r *rand.Rand) string { return getRandValue(r, []string{"address", "city"}) }
// State will generate a random state string
func State() string { return state(globalFaker.Rand) }
// State will generate a random state string
func (f *Faker) State() string { return state(f.Rand) }
func state(r *rand.Rand) string { return getRandValue(r, []string{"address", "state"}) }
// StateAbr will generate a random abbreviated state string
func StateAbr() string { return stateAbr(globalFaker.Rand) }
// StateAbr will generate a random abbreviated state string
func (f *Faker) StateAbr() string { return stateAbr(f.Rand) }
func stateAbr(r *rand.Rand) string { return getRandValue(r, []string{"address", "state_abr"}) }
// Zip will generate a random Zip code string
func Zip() string { return zip(globalFaker.Rand) }
// Zip will generate a random Zip code string
func (f *Faker) Zip() string { return zip(f.Rand) }
func zip(r *rand.Rand) string {
return replaceWithNumbers(r, getRandValue(r, []string{"address", "zip"}))
}
// Country will generate a random country string
func Country() string { return country(globalFaker.Rand) }
// Country will generate a random country string
func (f *Faker) Country() string { return country(f.Rand) }
func country(r *rand.Rand) string { return getRandValue(r, []string{"address", "country"}) }
// CountryAbr will generate a random abbreviated country string
func CountryAbr() string { return countryAbr(globalFaker.Rand) }
// CountryAbr will generate a random abbreviated country string
func (f *Faker) CountryAbr() string { return countryAbr(f.Rand) }
func countryAbr(r *rand.Rand) string { return getRandValue(r, []string{"address", "country_abr"}) }
// Latitude will generate a random latitude float64
func Latitude() float64 { return latitude(globalFaker.Rand) }
// Latitude will generate a random latitude float64
func (f *Faker) Latitude() float64 { return latitude(f.Rand) }
func latitude(r *rand.Rand) float64 { return toFixed((r.Float64()*180)-90, 6) }
// LatitudeInRange will generate a random latitude within the input range
func LatitudeInRange(min, max float64) (float64, error) {
return latitudeInRange(globalFaker.Rand, min, max)
}
// LatitudeInRange will generate a random latitude within the input range
func (f *Faker) LatitudeInRange(min, max float64) (float64, error) {
return latitudeInRange(f.Rand, min, max)
}
func latitudeInRange(r *rand.Rand, min, max float64) (float64, error) {
if min > max || min < -90 || min > 90 || max < -90 || max > 90 {
return 0, errors.New("invalid min or max range, must be valid floats and between -90 and 90")
}
return toFixed(float64Range(r, min, max), 6), nil
}
// Longitude will generate a random longitude float64
func Longitude() float64 { return longitude(globalFaker.Rand) }
// Longitude will generate a random longitude float64
func (f *Faker) Longitude() float64 { return longitude(f.Rand) }
func longitude(r *rand.Rand) float64 { return toFixed((r.Float64()*360)-180, 6) }
// LongitudeInRange will generate a random longitude within the input range
func LongitudeInRange(min, max float64) (float64, error) {
return longitudeInRange(globalFaker.Rand, min, max)
}
// LongitudeInRange will generate a random longitude within the input range
func (f *Faker) LongitudeInRange(min, max float64) (float64, error) {
return longitudeInRange(f.Rand, min, max)
}
func longitudeInRange(r *rand.Rand, min, max float64) (float64, error) {
if min > max || min < -180 || min > 180 || max < -180 || max > 180 {
return 0, errors.New("invalid min or max range, must be valid floats and between -180 and 180")
}
return toFixed(float64Range(r, min, max), 6), nil
}
func addAddressLookup() {
AddFuncLookup("address", Info{
Display: "Address",
Category: "address",
Display: "Address",
Category: "address",
Description: "Residential location including street, city, state, country and postal code",
Example: `{
"address": "364 Unionsville, Norfolk, Ohio 99536",
"street": "364 Unionsville",
"city": "Norfolk",
"state": "Ohio",
"zip": "99536",
"country": "Lesotho",
"latitude": 88.792592,
"longitude": 174.504681
}`,
Output: "map[string]any",
Output: "map[string]any",
ContentType: "application/json",
Generate: func(r *rand.Rand, m *MapParams, info *Info) (any, error) {
return address(r), nil
},
})
AddFuncLookup("city", Info{
Display: "City",
Category: "address",
Display: "City",
Category: "address",
Description: "Part of a country with significant population, often a central hub for culture and commerce",
Example: "Marcelside",
Output: "string",
Example: "Marcelside",
Output: "string",
Generate: func(r *rand.Rand, m *MapParams, info *Info) (any, error) {
return city(r), nil
},
})
AddFuncLookup("country", Info{
Display: "Country",
Category: "address",
Display: "Country",
Category: "address",
Description: "Nation with its own government and defined territory",
Example: "United States of America",
Output: "string",
Example: "United States of America",
Output: "string",
Generate: func(r *rand.Rand, m *MapParams, info *Info) (any, error) {
return country(r), nil
},
})
AddFuncLookup("countryabr", Info{
Display: "Country Abbreviation",
Category: "address",
Display: "Country Abbreviation",
Category: "address",
Description: "Shortened 2-letter form of a country's name",
Example: "US",
Output: "string",
Example: "US",
Output: "string",
Generate: func(r *rand.Rand, m *MapParams, info *Info) (any, error) {
return countryAbr(r), nil
},
})
AddFuncLookup("state", Info{
Display: "State",
Category: "address",
Display: "State",
Category: "address",
Description: "Governmental division within a country, often having its own laws and government",
Example: "Illinois",
Output: "string",
Example: "Illinois",
Output: "string",
Generate: func(r *rand.Rand, m *MapParams, info *Info) (any, error) {
return state(r), nil
},
})
AddFuncLookup("stateabr", Info{
Display: "State Abbreviation",
Category: "address",
Display: "State Abbreviation",
Category: "address",
Description: "Shortened 2-letter form of a country's state",
Example: "IL",
Output: "string",
Example: "IL",
Output: "string",
Generate: func(r *rand.Rand, m *MapParams, info *Info) (any, error) {
return stateAbr(r), nil
},
})
AddFuncLookup("street", Info{
Display: "Street",
Category: "address",
Display: "Street",
Category: "address",
Description: "Public road in a city or town, typically with houses and buildings on each side",
Example: "364 East Rapidsborough",
Output: "string",
Example: "364 East Rapidsborough",
Output: "string",
Generate: func(r *rand.Rand, m *MapParams, info *Info) (any, error) {
return street(r), nil
},
})
AddFuncLookup("streetname", Info{
Display: "Street Name",
Category: "address",
Display: "Street Name",
Category: "address",
Description: "Name given to a specific road or street",
Example: "View",
Output: "string",
Example: "View",
Output: "string",
Generate: func(r *rand.Rand, m *MapParams, info *Info) (any, error) {
return streetName(r), nil
},
})
AddFuncLookup("streetnumber", Info{
Display: "Street Number",
Category: "address",
Display: "Street Number",
Category: "address",
Description: "Numerical identifier assigned to a street",
Example: "13645",
Output: "string",
Example: "13645",
Output: "string",
Generate: func(r *rand.Rand, m *MapParams, info *Info) (any, error) {
return streetNumber(r), nil
},
})
AddFuncLookup("streetprefix", Info{
Display: "Street Prefix",
Category: "address",
Display: "Street Prefix",
Category: "address",
Description: "Directional or descriptive term preceding a street name, like 'East' or 'Main'",
Example: "Lake",
Output: "string",
Example: "Lake",
Output: "string",
Generate: func(r *rand.Rand, m *MapParams, info *Info) (any, error) {
return streetPrefix(r), nil
},
})
AddFuncLookup("streetsuffix", Info{
Display: "Street Suffix",
Category: "address",
Display: "Street Suffix",
Category: "address",
Description: "Designation at the end of a street name indicating type, like 'Avenue' or 'Street'",
Example: "land",
Output: "string",
Example: "land",
Output: "string",
Generate: func(r *rand.Rand, m *MapParams, info *Info) (any, error) {
return streetSuffix(r), nil
},
})
AddFuncLookup("zip", Info{
Display: "Zip",
Category: "address",
Display: "Zip",
Category: "address",
Description: "Numerical code for postal address sorting, specific to a geographic area",
Example: "13645",
Output: "string",
Example: "13645",
Output: "string",
Generate: func(r *rand.Rand, m *MapParams, info *Info) (any, error) {
return zip(r), nil
},
})
AddFuncLookup("latitude", Info{
Display: "Latitude",
Category: "address",
Display: "Latitude",
Category: "address",
Description: "Geographic coordinate specifying north-south position on Earth's surface",
Example: "-73.534056",
Output: "float",
Example: "-73.534056",
Output: "float",
Generate: func(r *rand.Rand, m *MapParams, info *Info) (any, error) {
return latitude(r), nil
},
})
AddFuncLookup("latituderange", Info{
Display: "Latitude Range",
Category: "address",
Display: "Latitude Range",
Category: "address",
Description: "Latitude number between the given range (default min=0, max=90)",
Example: "22.921026",
Output: "float",
Example: "22.921026",
Output: "float",
Params: []Param{
{Field: "min", Display: "Min", Type: "float", Default: "0", Description: "Minimum range"},
{Field: "max", Display: "Max", Type: "float", Default: "90", Description: "Maximum range"},
},
Generate: func(r *rand.Rand, m *MapParams, info *Info) (any, error) {
min, err := info.GetFloat64(m, "min")
if err != nil {
return nil, err
}
max, err := info.GetFloat64(m, "max")
if err != nil {
return nil, err
}
rangeOut, err := latitudeInRange(r, min, max)
if err != nil {
return nil, err
}
return rangeOut, nil
},
})
AddFuncLookup("longitude", Info{
Display: "Longitude",
Category: "address",
Display: "Longitude",
Category: "address",
Description: "Geographic coordinate indicating east-west position on Earth's surface",
Example: "-147.068112",
Output: "float",
Example: "-147.068112",
Output: "float",
Generate: func(r *rand.Rand, m *MapParams, info *Info) (any, error) {
return longitude(r), nil
},
})
AddFuncLookup("longituderange", Info{
Display: "Longitude Range",
Category: "address",
Display: "Longitude Range",
Category: "address",
Description: "Longitude number between the given range (default min=0, max=180)",
Example: "-8.170450",
Output: "float",
Example: "-8.170450",
Output: "float",
Params: []Param{
{Field: "min", Display: "Min", Type: "float", Default: "0", Description: "Minimum range"},
{Field: "max", Display: "Max", Type: "float", Default: "180", Description: "Maximum range"},
},
Generate: func(r *rand.Rand, m *MapParams, info *Info) (any, error) {
min, err := info.GetFloat64(m, "min")
if err != nil {
return nil, err
}
max, err := info.GetFloat64(m, "max")
if err != nil {
return nil, err
}
rangeOut, err := longitudeInRange(r, min, max)
if err != nil {
return nil, err
}
return rangeOut, nil
},
})
}

Some files were not shown because too many files have changed in this diff Show More