{"id":24557798,"url":"https://github.com/timclicks/ulid-lite","last_synced_at":"2025-04-19T03:15:12.251Z","repository":{"id":49726579,"uuid":"367598260","full_name":"timClicks/ulid-lite","owner":"timClicks","description":"Generate unique, yet sortable identifiers ","archived":false,"fork":false,"pushed_at":"2021-07-05T09:30:01.000Z","size":88,"stargazers_count":18,"open_issues_count":2,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-15T03:05:19.084Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/timClicks.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-05-15T10:08:14.000Z","updated_at":"2025-03-04T10:11:40.000Z","dependencies_parsed_at":"2022-09-26T20:41:22.405Z","dependency_job_id":null,"html_url":"https://github.com/timClicks/ulid-lite","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timClicks%2Fulid-lite","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timClicks%2Fulid-lite/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timClicks%2Fulid-lite/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timClicks%2Fulid-lite/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/timClicks","download_url":"https://codeload.github.com/timClicks/ulid-lite/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249598185,"owners_count":21297464,"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":[],"created_at":"2025-01-23T05:29:33.169Z","updated_at":"2025-04-19T03:15:12.234Z","avatar_url":"https://github.com/timClicks.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ulid-lite\n\n## About\n\nAn implementation of the [ULID] (\"Universally Unique Lexicographically Sortable Identifier\")\nstandard.\n\nA ULID is\n\n- 128-bit compatible with UUID\n- 1.21e+24 unique ULIDs per millisecond\n- Lexicographically sortable!\n- Canonically encoded as a 26 character string, as opposed to the 36 character UUID\n- Uses Crockford's base32 for better efficiency and readability (5 bits per character)\n- Case insensitive\n- No special characters (URL safe)\n\n[ULID]: https://github.com/ulid/spec\n\n## Usage\n\n### From the command line\n\nThe bundled application generates a ULID and prints it to stdout:\n\n```console\n$ ulid\n01F5QNHN4G55VHQHA8XG1N6H9H\n```\n\n### From Rust\n\nHere is a minimal application that uses this crate:\n\n```rust\nuse ulid::ulid;\n\nfn main() {\n    println!(\"{}\", ulid());\n}\n```\n\nThe primary API is the `ulid()` function, which returns a `String`.\nIf you would like access to the individual bits, then call `ulid_raw()`. \n\n```rust\nulid::ulid() -\u003e String\nulid::ulid_raw() -\u003e u128\n```\n\nFor more control, the `ulid::Ulid` type is also available.\n\n```rust\nulid::Ulid::new() -\u003e ulid::Ulid\n```\n\nThe `Ulid` struct is a wrapper around a `u128`, with a few extra methods.\n\n```rust\nlet id = ulid::Ulid::new();\n\n// They implement Display, LowerHex and UpperHex\nprintln!(\"{}\", id);\nprintln!(\"{:x}\", id);\nprintln!(\"{:X}\", id);\n```\n\nMore recent ULIDs are higher than older ones:\n\n```rust\nuse std::thread::sleep;\nuse std::time::Duration;\n\nlet a = ulid();\nsleep(Duration::from_millis(1));\nlet b = ulid();\nassert!(a \u003c b);\n```\n\nTo generate many `ulid::Ulid` values, you're recommended to use `UlidGenerator`.\nIt provides the ability to seed the internal pseudo-random number generator.\n\n```rust\n// use the system's clock as the initial seed...\nlet mut ulid_gen = ulid::UlidGenerator::new();\nlet ulids: Vec\u003c_\u003e = ulid_gen.take(1000).collect();\n```\n\n```rust\n// ...or use a fixed initial seed\nlet mut ulid_gen = ulid::UlidGenerator::from_seed(12345);\nlet ulid = ulid_gen.ulid();\n```\n\n### From C\n\nA C API is available at `lib/ulid.h`.  Here is a minimal application that generates and prints a ULID:\n\n```c\n#include \u003cstdio.h\u003e\n#include \"ulid.h\"\n\nint main(void) {\n    char str[27];\n\n    ulid_ctx ctx = ulid_init(0);\n    ulid_write_new(\u0026ctx, str, sizeof(str));\n\n    printf(\"%s\\n\", str);\n\n    return 0;\n}\n```\n\n`libulid` also provides access to creating binary (128 bit)\nULIDs and converting those to strings (this example is\nintentionally convoluted to showcase error handling):\n\n```c\n#include \u003cstdio.h\u003e\n#include \"ulid.h\"\n\nint main(void) {\n    ulid_ctx ctx;\n    ulid_t id;\n    char buf[64], *cur = buf;\n    int n, size = sizeof(buf);\n\n    ctx = ulid_init(0);\n    ulid_new(\u0026ctx, \u0026id);\n\n    n = snprintf(cur, size, \"Your ULID is \");\n    if (n \u003e= size)\n        return 1;\n    cur += n;\n    size -= n;\n\n    n = ulid_write(\u0026id, cur, size);\n    if (n \u003c 0) /* failed, typically buffer is too small */\n        return 1;\n    cur += n;\n    size -= n;\n\n    n = snprintf(cur, size, \".\");\n    if (n \u003e= size)\n        return 1;\n\n    printf(\"%s\\n\", buf);\n    return 0;\n}\n```\n\n\n## Installation\n\nAdd `ulid-lite` to your crate's Cargo.toml file:\n\n```toml\n[dependencies]\nulid-lite = \"0.6.1\"\n```\n\n### Building from source\n\nYou can download and install `ulid-lite` directly from the main branch of the upstream repository: \n\n```console\n$ cargo install --git https://github.com/timClicks/ulid-lite.git\n```\n\n### Building the C interface\n\nTo regenerate the `ulid.h` header file, run `make lib/ulid.h`.\n\nTo build the `libulid` shared library, run `make target/release/libulid.so`.\n\n\n## Contributing\n\nYou are very welcome to contribute to project in any form, however you must abide by the [Rust Code of Conduct].\n\n[Rust Code of Conduct]: https://www.rust-lang.org/policies/code-of-conduct\n\n### Non-code contributions\n\nYour contribution is important! Please [submit an issue] with your suggested change.\n\n[submit an issue]: https://github.com/timClicks/ulid-lite/issues/new\n\n### Code contributions\n\n\u003e Note: these instructions have only been tested on Ubuntu,\n\u003e please submit corrections/improvements for other operating systems.\n\n#### Setting up a development environment\n\nTo begin, you require the following tools:\n\n- A Rust installation that includes `rustc`, `rustup`, and `cargo`\n- `git`\n- `make`\n\n\nFrom the root of the project, run `setup-devenv` to install dependencies that are managed by `cargo` or `rustup`, such as [MIRI](https://github.com/rust-lang/miri):\n\n```console\n$ ./setup-devenv\n```\n\n#### Submitting changes\n\n`ulid-lite` follows the standard GitHub workflow for code changes.\nPlease fork the project, push commits to that fork and submit a pull request (PR).\n\nBefore submitting a PR, you should run `make test \u0026\u0026 make` from the project's root directory, rather than `cargo test`.\nThis will ensure that the MIRI tests run correctly and that artifacts can all be built.\n\n\n\n## Roadmap\n\n### PostgreSQL extension\n\nI would like to use this crate to develop pg_ulid extension.\n\n\n### More features\n\n- parsing pre-existing ULIDs \n- monotonicity within the same millisecond\n- overflow checks\n\n### More platforms\n\n`ulid-lite` is currently only built for Linux. Patches are welcome to support more platforms.\n\n\n## Why add another crate?\n\nI wanted to implement a crate with a minimalist feel. It is intended to be easy and fast to build.\n`ulid-lite` has minimal dependencies. This keeps build times fast and binary size small.\n\n`ulid` does not take a long time to compile:\n\n```console\n$ cargo clean\n$ cargo build --release\n   Compiling libc v0.2.94\n   Compiling lazy_static v0.2.11\n   Compiling rand v0.4.6\n   Compiling rand v0.3.23\n   Compiling xorshift v0.1.3\n   Compiling ulid-lite v0.4.0 (/.../ulid-lite)\n    Finished release [optimized] target(s) in 5.68s\n```\n\nPerhaps more importantly however, `ulid-lite` is very fast.\nA single CPU core can generate about 35,700 ULIDs per millisecond. \n\n```console\n$ cargo bench\n...\nrunning 2 tests\ntest benchmark_generation ... bench:          28 ns/iter (+/- 2)\ntest benchmark_serialized ... bench:          71 ns/iter (+/- 12)\n```\n\n## Acknowledgements\n\nI've relied on two other implementations to develop `ulid-lite`:\n\n\u003ctable\u003e\n\u003ctbody\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ca href=\"http://dylanh.art/\"\u003eDylan Hart\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003ca href=\"https://github.com/dylanhart/ulid-rs\"\u003egithub.com/dylanhart/ulid-rs\u003c/a\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ca href=\"https://github.com/mmacedoeu\"\u003eMarcos Macedo\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003ca href=\"https://github.com/mmacedoeu/rulid.rs\"\u003egithub.com/mmacedoeu/rulid.rs\u003c/a\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimclicks%2Fulid-lite","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftimclicks%2Fulid-lite","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimclicks%2Fulid-lite/lists"}