Skip to content

Commit

Permalink
Country and currency constants moved to separate packages (#19)
Browse files Browse the repository at this point in the history
* Country and currency constants moved to separate packages, module version updated to v2, several minor improvements

* added DecimalPlaces method for currency

* Updated readme

Co-authored-by: Vadim Maslov <[email protected]>
  • Loading branch information
vadim-mve and vadim-mve authored Jul 26, 2022
1 parent d4402fd commit f22a4da
Show file tree
Hide file tree
Showing 36 changed files with 4,425 additions and 4,510 deletions.
3 changes: 3 additions & 0 deletions .generator/package.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
"scripts": {
"generate": "node app.js"
},
"dependencies": {
"glob": "^7.1.6",
"glob-promise": "^4.1.0",
Expand Down
66 changes: 51 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,70 @@ This library has been created with the purpose to facilitate the store, validati

# Installation
```bash
go get github.com/mikekonan/go-types
go get github.com/mikekonan/go-types/v2
```
# Usage:
```go
//1. use in your structs
package main

import (
"encoding/json"
"fmt"
"log"

validation "github.com/go-ozzo/ozzo-validation/v4"
"github.com/mikekonan/go-types/v2/country"
"github.com/mikekonan/go-types/v2/country/alpha2"
"github.com/mikekonan/go-types/v2/country/alpha3"
"github.com/mikekonan/go-types/v2/country/name"
"github.com/mikekonan/go-types/v2/currency"
"github.com/mikekonan/go-types/v2/currency/code"
)

// 1. use in your structs
type User struct {
Name string `json:"name" db:"name"`
Country country.Alpha2Code `json:"country" db:"country"`
Name string `json:"name" db:"name"`
Country country.Alpha2Code `json:"country" db:"country"`
Currency currency.Code `json:"currency" db:"currency"`
}

func main() {
// 2. use in your wire
user := User{}
//2. use in your wire
json.Unmarshal([]byte(`{"name":"name", "country": "ca"}`), &user)
//3. check is set
user.Country.IsSet() //check user country is provided
//4. validate using ozzo-validation
if err := validation.ValidateStruct(&user, validation.Field(&user.Country)); err != nil {
_ = json.Unmarshal([]byte(`{"name":"name", "country": "CA", "currency": "CAD"}`), &user)

// 3. check is set
user.Country.IsSet()
user.Currency.IsSet()

// 4. validate using ozzo-validation
if err := validation.ValidateStruct(&user, validation.Field(&user.Country), validation.Field(&user.Currency)); err != nil {
log.Fatal(err)
}
//5. lookup by alpha2, alpha3, country name

// 5. lookup by alpha2, alpha3, country name
if userCountry, ok := country.ByAlpha2Code(user.Country); ok {
fmt.Printf("country name - '%s', alpha-2 - '%s', alpha-3 - '%s'", serCountry.Name(), userCountry.Alpha2Code(), userCountry.lpha3Code())
fmt.Printf("country name - '%s', alpha-2 - '%s', alpha-3 - '%s'", userCountry.Name(), userCountry.Alpha2Code(), userCountry.Alpha3Code())
}
//6. store in db
fmt.Println(user.Country.Value()) //prints 'CA'
//7. use specific countries

// 5. lookup by currency code
if userCurrency, ok := currency.ByCode(user.Currency); ok {
fmt.Printf("currency name - '%s', code - '%s', number - '%s', countries - '%s', decimal places - '%d'",
userCurrency.Currency(), userCurrency.Code(), userCurrency.Number(), userCurrency.Countries(), userCurrency.DecimalPlaces())
}

// 6. store in db
fmt.Println(user.Country.Value()) //prints 'CA'
fmt.Println(user.Currency.Value()) //prints 'CAN'

// 7. use specific country constants
fmt.Println(country.Canada.Alpha2Code())
fmt.Println("name:", name.Canada)
fmt.Println("alpha-2:", alpha2.CA)
fmt.Println("alpha-3:", alpha3.CAN)

// 8. use specific currency codes
fmt.Println(code.CAD)
}
```

Expand Down
10 changes: 5 additions & 5 deletions card/card.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ const (
gatewayCentury = 21
)

//CardDate represents as expired card date type with format MM/YY
// CardDate represents as expired card date type with format MM/YY
type CardDate string

//Value implementation of driver.Valuer
// Value implementation of driver.Valuer
func (cardDate CardDate) Value() (value driver.Value, err error) {
if err = cardDate.Validate(); err != nil {
return nil, err
Expand All @@ -28,7 +28,7 @@ func (cardDate CardDate) Value() (value driver.Value, err error) {
return cardDate.String(), nil
}

//UnmarshalJSON unmarshall implementation for CardDate
// UnmarshalJSON unmarshall implementation for CardDate
func (cardDate *CardDate) UnmarshalJSON(data []byte) error {
var str string
if err := json.Unmarshal(data, &str); err != nil {
Expand All @@ -50,7 +50,7 @@ func (cardDate *CardDate) UnmarshalJSON(data []byte) error {
return nil
}

//Validate implementation of ozzo-validation Validate interface
// Validate implementation of ozzo-validation Validate interface
func (cardDate CardDate) Validate() error {
if cardDate == "" {
return fmt.Errorf("invalid CardDate: cannot be blank")
Expand All @@ -72,7 +72,7 @@ func (cardDate CardDate) Validate() error {
return nil
}

//String implementation of Stringer interface
// String implementation of Stringer interface
func (cardDate CardDate) String() string {
return string(cardDate)
}
Expand Down
2 changes: 1 addition & 1 deletion card/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ components:
CardDate:
example: 01/06
type: string
x-go-type: github.com/mikekonan/go-types/card.CardDate
x-go-type: github.com/mikekonan/go-types/v2/card.CardDate
89 changes: 42 additions & 47 deletions country/.generator/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const fs = require("fs");
const transliterate = require("transliteration");
const yaml = require("yaml");

//For testing purpose we can use raw/countries
let codes = JSON.parse(fs.readFileSync(0, "utf8"));

codes = codes.map((code) => {
Expand Down Expand Up @@ -70,75 +71,69 @@ codes = codes.map((code) => {
return result;
});

const countriesTemplate = `package country
const countriesTemplate = `package name
import "github.com/mikekonan/go-types/v2/country"
const (
${codes
.map(
(code) =>
`//${code.name.key} represents '${code.name.value}' country name
${code.name.key} = Name("${code.name.value}")`
)
.join("\n")}
${codes.map(
(code) => `\t// ${code.key} represents '${code.name.value}' country name
${code.key} = country.Name("${code.name.value}")`
).join("\n")}
)
`;

const alpha2Template = `package country
const alpha2Template = `package alpha2
import "github.com/mikekonan/go-types/v2/country"
const (
${codes
.map(
(
code
) => `//${code.a2.key} represents '${code.a2.value}' country alpha-2 code
${code.a2.key} = Alpha2Code("${code.a2.value}")`
)
.join("\n")}
${codes.map(
(code) => `\t// ${code.a2.value} represents '${code.a2.value}' country alpha-2 code
${code.a2.value} = country.Alpha2Code("${code.a2.value}")`
).join("\n")}
)
`;

const alpha3Template = `package country
const alpha3Template = `package alpha3
import "github.com/mikekonan/go-types/v2/country"
const (
${codes
.map(
(
code
) => `//${code.a3.key} represents '${code.a3.value}' country alpha-3 code
${code.a3.key} = Alpha3Code("${code.a3.value}")`
)
.join("\n")}
${codes.map(
(code) => `\t// ${code.a3.value} represents '${code.a3.value}' country alpha-3 code
${code.a3.value} = country.Alpha3Code("${code.a3.value}")`
).join("\n")}
)
`;

const entitiesTemplate = `package country
var (
${codes
.map(
(code) => `//${code.key} represents '${code.name.value}' country
${code.key} = Country{
name: ${code.name.key},
alpha2: ${code.a2.key},
alpha3: ${code.a3.key},
${codes.map(
(code) => `\t// ${code.key} represents '${code.name.value}' country
${code.key} = Country{
name: \"${code.name.value}\",
alpha2: \"${code.a2.value}\",
alpha3: \"${code.a3.value}\",
}`
)
)
.join("\n")}
)
)
`;

const countryByCountryTemplate = `package country
var countryByName = map[Name]Country{
${codes.map((code) => `${code.name.key} : ${code.key}`).join(",\n")},
var CountryByName = map[string]Country{
${codes.map((code) => `\t\"${code.name.value}\" : ${code.key}`).join(",\n")},
}
var countryByAlpha2 = map[Alpha2Code]Country{
${codes.map((code) => `${code.a2.key} : ${code.key}`).join(",\n")},
var CountryByAlpha2 = map[string]Country{
${codes.map((code) => `\t\"${code.a2.value}\" : ${code.key}`).join(",\n")},
}
var countryByAlpha3 = map[Alpha3Code]Country{
${codes.map((code) => `${code.a3.key} : ${code.key}`).join(",\n")},
var CountryByAlpha3 = map[string]Country{
${codes.map((code) => `\t\"${code.a3.value}\" : ${code.key}`).join(",\n")},
}
`;

Expand All @@ -151,7 +146,7 @@ const spec = {
type: "string",
format: "iso3166-country",
enum: [...new Set(codes.map((code) => code.name.value))],
"x-go-type": "github.com/mikekonan/go-types/country.Name",
"x-go-type": "github.com/mikekonan/go-types/v2/country.Name",
},
CountryAlpha2: {
example: "AS",
Expand All @@ -160,7 +155,7 @@ const spec = {
minLength: 2,
maxLength: 2,
enum: [...new Set(codes.map((code) => code.a2.value))],
"x-go-type": "github.com/mikekonan/go-types/country.Alpha2Code",
"x-go-type": "github.com/mikekonan/go-types/v2/country.Alpha2Code",
},
CountryAlpha3: {
example: "USA",
Expand All @@ -169,22 +164,22 @@ const spec = {
minLength: 3,
maxLength: 3,
enum: [...new Set(codes.map((code) => code.a3.value))],
"x-go-type": "github.com/mikekonan/go-types/country.Alpha3Code",
"x-go-type": "github.com/mikekonan/go-types/v2/country.Alpha3Code",
}
},
},
};

let writeFiles = [
fs.writeFileSync("../name_gen.go", countriesTemplate, {
fs.writeFileSync("../name/name_gen.go", countriesTemplate, {
encoding: "utf8",
flag: "w",
}),
fs.writeFileSync("../alpha2_gen.go", alpha2Template, {
fs.writeFileSync("../alpha2/alpha_2_gen.go", alpha2Template, {
encoding: "utf8",
flag: "w",
}),
fs.writeFileSync("../alpha3_gen.go", alpha3Template, {
fs.writeFileSync("../alpha3/alpha_3_gen.go", alpha3Template, {
encoding: "utf8",
flag: "w",
}),
Expand Down
1 change: 1 addition & 0 deletions country/.generator/raw/countries

Large diffs are not rendered by default.

57 changes: 57 additions & 0 deletions country/alpha2.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package country

import (
"database/sql/driver"
"encoding/json"
)

// Alpha2Code represents alpha-2 code
type Alpha2Code string

// UnmarshalJSON unmarshall implementation for alpha2code
func (code *Alpha2Code) UnmarshalJSON(data []byte) error {
var str string
if err := json.Unmarshal(data, &str); err != nil {
return err
}

enumValue := Alpha2Code(str)
if _, err := ByAlpha2CodeErr(enumValue); err != nil {
return err
}

*code = enumValue
return nil
}

// Value implementation of driver.Valuer
func (code Alpha2Code) Value() (value driver.Value, err error) {
if code == "" {
return "", nil
}

var country Country

if country, err = ByAlpha2CodeErr(code); err != nil {
return nil, err
}

return country.Alpha2Code().String(), nil
}

// Validate implementation of ozzo-validation Validate interface
func (code Alpha2Code) Validate() (err error) {
_, err = ByAlpha2CodeErr(code)

return
}

// IsSet indicates if Name is set
func (code Alpha2Code) IsSet() bool {
return len(string(code)) > 0
}

// String implementation of Stringer interface
func (code Alpha2Code) String() string {
return string(code)
}
Loading

0 comments on commit f22a4da

Please sign in to comment.