{"id":51345778,"url":"https://github.com/yuly3/vouched","last_synced_at":"2026-07-02T11:35:09.073Z","repository":{"id":361417956,"uuid":"1254028808","full_name":"yuly3/vouched","owner":"yuly3","description":"Derive validated Rust newtypes with generated TryFrom implementations.","archived":false,"fork":false,"pushed_at":"2026-05-30T14:17:24.000Z","size":77,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-30T16:05:38.646Z","etag":null,"topics":["derive","newtype","no-std","proc-macro","rust","rust-crate","rust-lang","validation"],"latest_commit_sha":null,"homepage":"https://crates.io/crates/vouched","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yuly3.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-30T04:05:51.000Z","updated_at":"2026-05-30T14:17:22.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/yuly3/vouched","commit_stats":null,"previous_names":["yuly3/vouched"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/yuly3/vouched","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuly3%2Fvouched","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuly3%2Fvouched/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuly3%2Fvouched/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuly3%2Fvouched/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yuly3","download_url":"https://codeload.github.com/yuly3/vouched/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuly3%2Fvouched/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35045923,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-02T02:00:06.368Z","response_time":173,"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":["derive","newtype","no-std","proc-macro","rust","rust-crate","rust-lang","validation"],"created_at":"2026-07-02T11:35:07.105Z","updated_at":"2026-07-02T11:35:09.058Z","avatar_url":"https://github.com/yuly3.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# vouched\n\n`vouched` provides a derive macro for tuple-struct newtypes whose values are vouched for after validation.\n\n## Install\n\n```toml\n[dependencies]\nvouched = \"0.3\"\n```\n\n## Quick start\n\n```rust\nuse vouched::Vouched;\n\n#[derive(Debug, PartialEq, Eq, Vouched)]\n#[vouched(len(1..=64), chars('a'..='z', '0'..='9', '_'), impls(try_from(\u0026str)))]\nstruct Slug(String);\nimpl Slug {\n    fn as_str(\u0026self) -\u003e \u0026str {\n        \u0026self.0\n    }\n}\n\nlet slug = Slug::try_from(\"hello_123\")?;\nassert_eq!(slug.as_str(), \"hello_123\");\n```\n\n## Examples\n\nSee [crates/vouched/examples](crates/vouched/examples) for more detailed, executable examples.\n\n```sh\ncargo run -p vouched --example \u003cname\u003e\n```\n\n## Supported Markers\n\n- `len(range)`: validates string length by Unicode scalar value count. Leading and trailing whitespace count.\n- `range(range)`: validates numeric bounds for `i8`, `i16`, `i32`, `i64`, `i128`, `u8`, `u16`, `u32`, `u64`, `u128`, `f32`, and `f64`.\n- `chars(...)`: validates allowed characters by string literal, char literal, or inclusive char range.\n\n`len(...)`, `range(...)`, and `chars(...)` can each be specified at most once.\nTo combine character sets, put all sources in one marker, such as `chars('a'..='z', '0'..='9', '_')`.\n\n`range(...)` type-checks the bound expressions against the inner numeric type and generates runtime validation.\nFloat ranges reject an actual `NaN` value as not comparable.\nFloat bound expressions must not evaluate to `NaN`; Rust float comparison rules make a `NaN` bound ineffective.\n`range(...)` does not guarantee the range is non-empty; for example, a contradictory range remains the user's constraint.\n\nValidation returns the first error encountered. When multiple markers or multiple constraints fail, the exact evaluation order is an implementation detail. The implementation may move expensive whole-string validations later to reduce validation cost.\n\n## Generated API\n\n`#[derive(Vouched)]` generates `TryFrom` impls, a `\u003cTypeName\u003eVouchedError` enum, `Display`, `core::error::Error`, and `vouched::VouchedError`.\nUse `impls(try_from(...))` to request additional `TryFrom` implementations before validation.\nSupported sources are fallible fixed-width integer conversions and `\u0026str` for string validation newtypes with supported owned string inner types: `String`, `Box\u003cstr\u003e`, `Rc\u003cstr\u003e`, and `Arc\u003cstr\u003e`.\nFor `impls(try_from(\u0026str))`, the generated implementation validates the borrowed input before constructing the inner value, so invalid inputs do not allocate. Custom string wrapper inner types are not supported by this impl.\nThe default error enum visibility matches the derived type visibility.\nUse `#[vouched(error(name = CustomErrorName, vis = pub(crate)), ...)]` to override the generated error enum name or visibility.\nRust visibility rules still apply: if a public derived type exposes a less-visible error type through `TryFrom::Error`, rustc rejects the generated impl.\n\n## Feature flags\n\n| features | crate mode | available |\n| --- | --- | --- |\n| default / `std` | `std` | derive macro, core errors, generated errors, erased `Error` |\n| `alloc` without default | `no_std` + `alloc` | derive macro, core errors, generated errors, erased `Error` |\n| no default features | `no_std` | derive macro, core errors, generated errors; no erased `Error` |\n| `valuable` | `no_std` + `alloc` | all `alloc` items plus `valuable::Valuable` impls for structured error observation |\n\n`std` enables `alloc`. `valuable` also enables `alloc`.\n\n## Limitations\n\n- Only tuple structs with exactly one field are supported.\n- The default generated error enum name is `\u003cTypeName\u003eVouchedError`; use `error(name = CustomErrorName)` to avoid local name collisions.\n- Integer `impls(try_from(...))` supports only fallible fixed-width conversions among `i8`, `i16`, `i32`, `i64`, `i128`, `u8`, `u16`, `u32`, `u64`, and `u128`.\n- `impls(try_from(\u0026str))` supports only `len(...)` and/or `chars(...)`, cannot be mixed with integer sources, and requires `String`, `Box\u003cstr\u003e`, `Rc\u003cstr\u003e`, or `Arc\u003cstr\u003e` as the inner type. Custom string wrapper inners and borrowed inners that store the input lifetime are not supported.\n- `range(...)` supports fixed-width integers plus `f32` and `f64`; `isize`, `usize`, and custom ordered types are not supported.\n- `len(...)` works on `AsRef\u003cstr\u003e` values and measures untrimmed Unicode scalar values, not bytes.\n- `chars(...)` works on `AsRef\u003cstr\u003e` values and validates untrimmed Unicode scalar values.\n\n## Versioning\n\nWhile `vouched` is in `0.x`, breaking changes to public APIs, generated APIs, or documented behavior require a minor version bump.\nPatch releases are limited to bug fixes, documentation updates, and non-breaking additions.\n\nThe current MSRV is Rust 1.86. MSRV changes are not shipped in patch releases; while `vouched` is in `0.x`, an MSRV bump is treated as a possibly-breaking compatibility change and shipped in a minor release with release notes.\n\nAfter `1.0.0`, `vouched` follows SemVer for public APIs and documented behavior.\n\n## License\n\nLicensed under either of\n\n- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or \u003chttps://www.apache.org/licenses/LICENSE-2.0\u003e)\n- MIT license ([LICENSE-MIT](LICENSE-MIT) or \u003chttps://opensource.org/licenses/MIT\u003e)\n\nat your option.\n\n## Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyuly3%2Fvouched","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyuly3%2Fvouched","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyuly3%2Fvouched/lists"}