{"id":19269144,"url":"https://github.com/typst/unscanny","last_synced_at":"2025-05-16T14:08:08.681Z","repository":{"id":57674048,"uuid":"482246084","full_name":"typst/unscanny","owner":"typst","description":"Painless string scanning.","archived":false,"fork":false,"pushed_at":"2024-11-04T10:34:14.000Z","size":16,"stargazers_count":55,"open_issues_count":0,"forks_count":7,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-04-12T12:51:46.565Z","etag":null,"topics":["parsing","scanning","tokenization"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/typst.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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},"funding":{"github":["typst"]}},"created_at":"2022-04-16T12:19:15.000Z","updated_at":"2025-04-04T04:45:19.000Z","dependencies_parsed_at":"2024-11-09T20:18:57.109Z","dependency_job_id":"d3c731a9-5e5f-4404-8cb9-d6ea22ded566","html_url":"https://github.com/typst/unscanny","commit_stats":{"total_commits":5,"total_committers":1,"mean_commits":5.0,"dds":0.0,"last_synced_commit":"a6614efa67d4b796948d614071bc0b33e5c8cce5"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/typst%2Funscanny","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/typst%2Funscanny/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/typst%2Funscanny/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/typst%2Funscanny/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/typst","download_url":"https://codeload.github.com/typst/unscanny/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254544146,"owners_count":22088807,"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":["parsing","scanning","tokenization"],"created_at":"2024-11-09T20:18:39.426Z","updated_at":"2025-05-16T14:08:06.163Z","avatar_url":"https://github.com/typst.png","language":"Rust","readme":"# unscanny\n[![Crates.io](https://img.shields.io/crates/v/unscanny.svg)](https://crates.io/crates/unscanny)\n[![Documentation](https://docs.rs/unscanny/badge.svg)](https://docs.rs/unscanny)\n\nPainless string scanning.\n\n```toml\n[dependencies]\nunscanny = \"0.1\"\n```\n\nBasically, you'll want to use this crate if it's too much pain to solve your\nproblem with a bare `chars()` iterator. Speaking more broadly, `unscanny` is\nuseful in these situations:\n- You need to parse simple flat grammars (dates, times, custom stuff, ...) and\n  want an interface that's a bit more convenient to use than a simple char\n  iterator.\n- You're hand-writing a tokenizer.\n\nThe `Scanner` keeps an internal cursor, allows you to peek around it, advance it\nbeyond chars or other patterns and easily slice substrings before and after the\ncursor.\n\n# Example\nRecognizing and parsing a simple comma separated list of floats.\n```rust\nlet mut s = Scanner::new(\" +12 , -15.3, 14.3  \");\nlet mut nums = vec![];\nwhile !s.done() {\n    s.eat_whitespace();\n    let start = s.cursor();\n    s.eat_if(['+', '-']);\n    s.eat_while(char::is_ascii_digit);\n    s.eat_if('.');\n    s.eat_while(char::is_ascii_digit);\n    nums.push(s.from(start).parse::\u003cf64\u003e().unwrap());\n    s.eat_whitespace();\n    s.eat_if(',');\n}\nassert_eq!(nums, [12.0, -15.3, 14.3]);\n```\n\n## Safety\nThis crate internally uses unsafe code for better performance. However, all\nunsafe code is documented with justification for why it's safe, all accesses are\nchecked in debug mode and everything is tested.\n\n## License\nThis crate is dual-licensed under the MIT and Apache 2.0 licenses.\n","funding_links":["https://github.com/sponsors/typst"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftypst%2Funscanny","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftypst%2Funscanny","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftypst%2Funscanny/lists"}