{"id":31054461,"url":"https://github.com/alexhcjp/purify","last_synced_at":"2026-02-13T23:08:22.548Z","repository":{"id":257805692,"uuid":"865631123","full_name":"AlexHCJP/purify","owner":"AlexHCJP","description":"Purify is a Go library for struct validation based on tags. It allows you to easily validate data within structs using purify tags, making your code cleaner and easier to maintain.","archived":false,"fork":false,"pushed_at":"2024-10-01T00:08:54.000Z","size":10,"stargazers_count":3,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-21T19:39:39.703Z","etag":null,"topics":["form","go","golang","validator"],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/github.com/contributors-company/purify","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AlexHCJP.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-30T21:13:07.000Z","updated_at":"2025-04-05T16:08:27.000Z","dependencies_parsed_at":null,"dependency_job_id":"15d5549f-7cc3-4e1c-a518-a7f0d6a3de9a","html_url":"https://github.com/AlexHCJP/purify","commit_stats":null,"previous_names":["contributors-company/purify","alexhcjp/purify"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/AlexHCJP/purify","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexHCJP%2Fpurify","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexHCJP%2Fpurify/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexHCJP%2Fpurify/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexHCJP%2Fpurify/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AlexHCJP","download_url":"https://codeload.github.com/AlexHCJP/purify/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexHCJP%2Fpurify/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275198308,"owners_count":25422284,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-15T02:00:09.272Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["form","go","golang","validator"],"created_at":"2025-09-15T03:11:26.838Z","updated_at":"2026-02-13T23:08:22.491Z","avatar_url":"https://github.com/AlexHCJP.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Purify\n\n**Purify** is a Go library for struct validation based on tags. It allows you to easily validate data within structs using `purify` tags, making your code cleaner and easier to maintain.\n\n## Table of Contents\n\n- [Getting Started](#getting-started)\n  - [Installation](#installation)\n  - [Requirements](#requirements)\n- [Usage](#usage)\n  - [Example](#example)\n  - [Available Validation Tags](#available-validation-tags)\n- [Custom Validators](#custom-validators)\n  - [Creating a Custom Validator](#creating-a-custom-validator)\n  - [Password Validation Example](#password-validation-example)\n- [Error Handling](#error-handling)\n- [Testing](#testing)\n- [Contributing](#contributing)\n- [License](#license)\n- [Author](#author)\n- [Acknowledgments](#acknowledgments)\n\n## Getting Started\n\n### Installation\n\nInstall the library using `go get`:\n\n```bash\ngo get github.com/contributors-company/purify\n```\n\nImport the package into your project:\n\n```go\nimport \"github.com/contributors-company/purify\"\n```\n\n### Requirements\n\n- Go 1.13 or higher\n\n## Usage\n\nPurify allows you to validate struct fields using `purify` tags in your struct definitions.\n\n### Example\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n    \"github.com/contributors-company/purify\"\n)\n\ntype User struct {\n    Email    string `json:\"email\" purify:\"required|email\"`\n    Username string `json:\"username\" purify:\"required|min(3)|max(20)\"`\n    Age      int    `json:\"age\" purify:\"min(18)|max(99)\"`\n}\n\nfunc main() {\n    user := User{\n        Email:    \"example@example.com\",\n        Username: \"example_user\",\n        Age:      25,\n    }\n\n    // Validate the struct\n    err := purify.ValidateStruct(user)\n    if err != nil {\n        fmt.Println(\"Validation error:\", err)\n    } else {\n        fmt.Println(\"Validation successful\")\n    }\n}\n```\n\nIn this example:\n\n- The `Email` field must be filled and contain a valid email address.\n- The `Username` field must be filled, have a length of at least 3 and at most 20 characters.\n- The `Age` field must be at least 18 and at most 99.\n\n### Available Validation Tags\n\n- `required` — checks that the field is not empty.\n- `email` — checks that the field contains a valid email address.\n- `min(n)` — checks that the field's value is not less than `n`. For strings, this is the length of the string; for numbers, the value itself.\n- `max(n)` — checks that the field's value is not greater than `n`. For strings, this is the length of the string; for numbers, the value itself.\n\n**Example of tag usage:**\n\n```go\ntype Product struct {\n    Name  string  `json:\"name\" purify:\"required|min(3)|max(50)\"`\n    Price float64 `json:\"price\" purify:\"required|min(0.01)\"`\n}\n```\n\n## Custom Validators\n\nPurify provides the ability to create your own validators to extend the library's functionality to meet your project's specific requirements.\n\n### Creating a Custom Validator\n\nTo create a custom validator, define a function that matches the `ValidatorFunc` type and register it using `RegisterValidator`.\n\n**`ValidatorFunc` type:**\n\n```go\ntype ValidatorFunc func(fieldValue string, param string) string\n```\n\n- `fieldValue` — the value of the field to be validated.\n- `param` — the parameter passed in the validation tag (if any).\n- The function should return an error message string or an empty string if the validation passes.\n\n**Example of custom validators:**\n\n```go\nfunc Min() ValidatorFunc {\n    return func(fieldValue string, param string) string {\n        minLength, _ := strconv.Atoi(param)\n        if len(fieldValue) \u003c minLength {\n            return fmt.Sprintf(\"minimum length is %s characters\", param)\n        }\n        return \"\"\n    }\n}\n\nfunc Max() ValidatorFunc {\n    return func(fieldValue string, param string) string {\n        maxLength, _ := strconv.Atoi(param)\n        if len(fieldValue) \u003e maxLength {\n            return fmt.Sprintf(\"maximum length is %s characters\", param)\n        }\n        return \"\"\n    }\n}\n\nfunc Required() ValidatorFunc {\n    return func(fieldValue string, _ string) string {\n        if fieldValue == \"\" {\n            return \"required field\"\n        }\n        return \"\"\n    }\n}\n\nfunc Email() ValidatorFunc {\n    return func(fieldValue string, _ string) string {\n        emailRegex := `^[a-zA-Z0-9._%+\\-]+@[a-zA-Z0-9.\\-]+\\.[a-zA-Z]{2,}$`\n        matched, _ := regexp.MatchString(emailRegex, fieldValue)\n        if !matched {\n            return \"invalid email\"\n        }\n        return \"\"\n    }\n}\n\n// Register the validators\nfunc init() {\n    RegisterValidator(\"min\", Min())\n    RegisterValidator(\"max\", Max())\n    RegisterValidator(\"required\", Required())\n    RegisterValidator(\"email\", Email())\n}\n```\n\n### Password Validation Example\n\nSuppose you want to add password validation to meet certain requirements, such as:\n\n- Minimum length of 8 characters.\n- At least one digit.\n- At least one uppercase letter.\n\n**Creating a custom validator for password:**\n\n```go\nfunc Password() ValidatorFunc {\n    return func(fieldValue string, _ string) string {\n        if len(fieldValue) \u003c 8 {\n            return \"password must be at least 8 characters long\"\n        }\n        if !regexp.MustCompile(`[0-9]`).MatchString(fieldValue) {\n            return \"password must contain at least one digit\"\n        }\n        if !regexp.MustCompile(`[A-Z]`).MatchString(fieldValue) {\n            return \"password must contain at least one uppercase letter\"\n        }\n        return \"\"\n    }\n}\n\n// Register the validator\nfunc init() {\n    RegisterValidator(\"password\", Password())\n}\n```\n\n**Using the custom validator in a struct:**\n\n```go\ntype Credentials struct {\n    Password string `json:\"password\" purify:\"required|password\"`\n}\n```\n\n**Usage example:**\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n    \"github.com/contributors-company/purify\"\n)\n\ntype Credentials struct {\n    Password string `json:\"password\" purify:\"required|password\"`\n}\n\nfunc main() {\n    creds := Credentials{\n        Password: \"Passw1\", // Invalid password\n    }\n\n    // Validate the struct\n    err := purify.ValidateStruct(creds)\n    if err != nil {\n        validationErrors := err.(purify.ValidationError)\n        for field, errors := range validationErrors.Errors {\n            fmt.Printf(\"Field '%s' has the following errors:\\n\", field)\n            for _, errMsg := range errors {\n                fmt.Printf(\"- %s\\n\", errMsg)\n            }\n        }\n    } else {\n        fmt.Println(\"Validation successful\")\n    }\n}\n```\n\n**Expected output:**\n\n```\nField 'Password' has the following errors:\n- password must be at least 8 characters long\n- password must contain at least one uppercase letter\n```\n\n## Error Handling\n\nThe `ValidateStruct` function returns `nil` if there are no validation errors or an error object with the following structure:\n\n```json\n{\n    \"errors\": {\n        \"field_name\": [\"error_message1\", \"error_message2\"],\n        \"another_field\": [\"error_message\"]\n    },\n    \"message\": \"General error message\"\n}\n```\n\n**Example of error handling:**\n\n```go\nerr := purify.ValidateStruct(user)\nif err != nil {\n    validationErrors := err.(purify.ValidationError)\n    for field, errors := range validationErrors.Errors {\n        fmt.Printf(\"Field '%s' has the following errors:\\n\", field)\n        for _, errMsg := range errors {\n            fmt.Printf(\"- %s\\n\", errMsg)\n        }\n    }\n} else {\n    fmt.Println(\"Validation successful\")\n}\n```\n\n## Testing\n\nYou can run tests using the command:\n\n```bash\ngo test\n```\n\nSample test from the library:\n\n```go\npackage purify\n\nimport (\n    \"testing\"\n)\n\ntype TestStruct struct {\n    Name     string `json:\"name\" purify:\"required|min(3)|max(20)\"`\n    Email    string `json:\"email\" purify:\"required|email\"`\n    Password string `json:\"password\" purify:\"required|password\"`\n}\n\nfunc TestValidator(t *testing.T) {\n    s := TestStruct{\n        Name:     \"Al\",\n        Email:    \"invalid_email\",\n        Password: \"pass\",\n    }\n\n    // Validate the struct\n    err := ValidateStruct(s)\n    if err == nil {\n        t.Errorf(\"Expected validation error, got nil\")\n    } else {\n        validationErrors := err.(ValidationError)\n        if len(validationErrors.Errors) != 3 {\n            t.Errorf(\"Expected 3 validation errors, got %d\", len(validationErrors.Errors))\n        }\n    }\n}\n```\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexhcjp%2Fpurify","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexhcjp%2Fpurify","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexhcjp%2Fpurify/lists"}