{"id":18560958,"url":"https://github.com/artichoke/focaccia","last_synced_at":"2025-06-15T04:05:16.877Z","repository":{"id":36997941,"uuid":"284314214","full_name":"artichoke/focaccia","owner":"artichoke","description":"🍞 no_std Unicode case folding comparisons","archived":false,"fork":false,"pushed_at":"2025-06-10T00:04:05.000Z","size":2264,"stargazers_count":9,"open_issues_count":0,"forks_count":1,"subscribers_count":4,"default_branch":"trunk","last_synced_at":"2025-06-10T01:20:30.860Z","etag":null,"topics":["artichoke","case","case-folding","no-std","rust","rust-crate","unicode","unicode-case-folding","utf-8"],"latest_commit_sha":null,"homepage":"https://crates.io/crates/focaccia","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/artichoke.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","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,"zenodo":null}},"created_at":"2020-08-01T18:13:41.000Z","updated_at":"2025-06-02T01:45:10.000Z","dependencies_parsed_at":"2023-09-26T04:45:58.248Z","dependency_job_id":"511f5aab-98a6-4b10-9014-54099f378ee5","html_url":"https://github.com/artichoke/focaccia","commit_stats":{"total_commits":245,"total_committers":4,"mean_commits":61.25,"dds":"0.38367346938775515","last_synced_commit":"93278ae04213e73ba7d71ba76e27dc1105a6b49f"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/artichoke/focaccia","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artichoke%2Ffocaccia","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artichoke%2Ffocaccia/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artichoke%2Ffocaccia/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artichoke%2Ffocaccia/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/artichoke","download_url":"https://codeload.github.com/artichoke/focaccia/tar.gz/refs/heads/trunk","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artichoke%2Ffocaccia/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259919352,"owners_count":22932069,"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","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":["artichoke","case","case-folding","no-std","rust","rust-crate","unicode","unicode-case-folding","utf-8"],"created_at":"2024-11-06T22:05:18.077Z","updated_at":"2025-06-15T04:05:16.856Z","avatar_url":"https://github.com/artichoke.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# focaccia\n\n[![GitHub Actions](https://github.com/artichoke/focaccia/workflows/CI/badge.svg)](https://github.com/artichoke/focaccia/actions)\n[![Code Coverage](https://codecov.artichokeruby.org/focaccia/badges/flat.svg?nocache=2)](https://codecov.artichokeruby.org/focaccia/index.html)\n[![Discord](https://img.shields.io/discord/607683947496734760)](https://discord.gg/QCe2tp2)\n[![Twitter](https://img.shields.io/twitter/follow/artichokeruby?label=Follow\u0026style=social)](https://twitter.com/artichokeruby)\n\u003cbr\u003e\n[![Crate](https://img.shields.io/crates/v/focaccia.svg)](https://crates.io/crates/focaccia)\n[![API](https://docs.rs/focaccia/badge.svg)](https://docs.rs/focaccia)\n[![API trunk](https://img.shields.io/badge/docs-trunk-blue.svg)](https://artichoke.github.io/focaccia/focaccia/)\n\nUnicode case folding methods for case-insensitive string comparisons. Used to\nimplement case folding operations on the [`Symbol`] and [`String`] classes in\nthe Ruby Core implementation in [Artichoke Ruby][artichoke].\n\n[`symbol`]: https://ruby-doc.org/core-3.1.2/Symbol.html\n[`string`]: https://ruby-doc.org/core-3.1.2/String.html\n[artichoke]: https://github.com/artichoke/artichoke\n\nFocaccia supports full, ASCII, and Turkic [Unicode case folding] equality and\nordering comparisons.\n\n[unicode case folding]: https://www.w3.org/International/wiki/Case_folding\n\n\u003e One of the most common things that software developers do is \"normalize\" text\n\u003e for the purposes of comparison. And one of the most basic ways that developers\n\u003e are taught to normalize text for comparison is to compare it in a \"case\n\u003e insensitive\" fashion. In other cases, developers want to compare strings in a\n\u003e case sensitive manner. Unicode defines upper, lower, and title case properties\n\u003e for characters, plus special cases that impact specific language's use of\n\u003e text. (W3C, Case Folding)\n\n_focaccia_ is a flat Italian bread. The focaccia crate compares UTF-8 strings by\nflattening them to folded downcase. Artichoke goes well with focaccia.\n\n## Usage\n\nAdd this to your `Cargo.toml`:\n\n```toml\n[dependencies]\nfocaccia = \"2.0.0\"\n```\n\nThen make case insensitive string comparisons like:\n\n```rust\nuse core::cmp::Ordering;\nuse focaccia::CaseFold;\n\nlet fold = CaseFold::Full;\nassert_eq!(fold.casecmp(\"MASSE\", \"Maße\"), Ordering::Equal);\nassert_eq!(fold.casecmp(\"São Paulo\", \"Sao Paulo\"), Ordering::Greater);\n\nassert!(fold.case_eq(\"MASSE\", \"Maße\"));\nassert!(!fold.case_eq(\"São Paulo\", \"Sao Paulo\"));\n```\n\nFor text known to be ASCII, Focaccia can make a more performant comparison\ncheck:\n\n```rust\nuse core::cmp::Ordering;\nuse focaccia::CaseFold;\n\nlet fold = CaseFold::Ascii;\nassert_eq!(fold.casecmp(\"Crate: focaccia\", \"Crate: FOCACCIA\"), Ordering::Equal);\nassert_eq!(fold.casecmp(\"Fabled\", \"failed\"), Ordering::Less);\n\nassert!(fold.case_eq(\"Crate: focaccia\", \"Crate: FOCACCIA\"));\nassert!(!fold.case_eq(\"Fabled\", \"failed\"));\n```\n\nASCII case comparison can be checked on a byte slice:\n\n```rust\nuse core::cmp::Ordering;\nuse focaccia::{ascii_casecmp, ascii_case_eq};\n\nassert_eq!(ascii_casecmp(b\"Artichoke Ruby\", b\"artichoke ruby\"), Ordering::Equal);\nassert!(ascii_case_eq(b\"Artichoke Ruby\", b\"artichoke ruby\"));\n```\n\nTurkic case folding is similar to full case folding with additional mappings for\n[dotted and dotless I]:\n\n[dotted and dotless i]: https://en.wikipedia.org/wiki/Dotted_and_dotless_I\n\n```rust\nuse core::cmp::Ordering;\nuse focaccia::CaseFold;\n\nlet fold = CaseFold::Turkic;\nassert_eq!(fold.casecmp(\"İstanbul\", \"istanbul\"), Ordering::Equal);\nassert_ne!(fold.casecmp(\"İstanbul\", \"Istanbul\"), Ordering::Equal);\n\nassert!(fold.case_eq(\"İstanbul\", \"istanbul\"));\nassert!(!fold.case_eq(\"İstanbul\", \"Istanbul\"));\n```\n\n## Implementation\n\nFocaccia generates conversion tables from Unicode Data Files. Focaccia\nimplements case folding as defined in the [Unicode standard][casemap] (see\n[`CaseFolding.txt`]).\n\n[casemap]: https://unicode.org/faq/casemap_charprop.html#casemap\n[`casefolding.txt`]: CaseFolding.txt\n\n## `no_std`\n\nFocaccia is `no_std` compatible and only depends on `core`. Focaccia does not\nlink to `alloc` in its `no_std` configuration.\n\n### Minimum Supported Rust Version\n\nThis crate requires at least Rust 1.83.0. This version can be bumped in minor\nreleases.\n\n## Unicode Version\n\nFocaccia implements Unicode case folding with the Unicode 16.0.0 case folding\nruleset.\n\nEach new release of Unicode may bring updates to the `CaseFolding.txt` which is\nthe source for the folding mappings in this crate. Updates to the case folding\nrules will be accompanied with a minor version bump.\n\n## License\n\n`focaccia` is licensed under the [MIT License](LICENSE) (c) Ryan Lopopolo.\n\n`focaccia` includes Unicode Data Files which are subject to the [Unicode Terms\nof Use] and [Unicode License v3](LICENSE-UNICODE) (c) 1991-2024 Unicode, Inc.\n\n[unicode terms of use]: https://www.unicode.org/copyright.html\n\nGenerated files in this repository are marked with `// @generated` comments and\nthe Unicode copyright. These generated files incorporate data derived from the\nUnicode Data Files. More details about the generation process can be found in\n[`scripts/gen_case_lookups.rb`]. The generated sources created by this script\nare subject to both the MIT License contained in this repository and the Unicode\nLicense v3.\n\n[`scripts/gen_case_lookups.rb`]: scripts/gen_case_lookups.rb\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fartichoke%2Ffocaccia","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fartichoke%2Ffocaccia","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fartichoke%2Ffocaccia/lists"}