Create custom ID types that are guaranteed to be valid `RecordID` in SurrealDB

Overview

Crates.io Documentation Codecov Dependency status

surreal-id

The surreal-id crate offers a standardized way to create and validate IDs in your application for usage with SurrealDB. Using the NewId trait, the crate streamlines the ID type defining process with a blanket implementation of new that handles errors like malformed or empty IDs, and ensures consistency with associated table names and functionality with SurrealDB. This also enables developers to create custom IDs in their application layer and serialize and deserialize those types safely from SurrealDB, ensuring type safety and consistency throughout the app.

Example

use serde::{Deserialize, Serialize};
use surreal_id::NewId;
use surrealdb::{opt::RecordId, sql::Id};

pub const USERS_TABLE: &str = "users";

#[derive(Serialize, Deserialize)]
pub struct UserId(RecordId);

impl NewId for UserId {
    const TABLE: &'static str = USERS_TABLE;

    fn from_inner_id<T: Into<Id>>(inner_id: T) -> Self {
        UserId(RecordId {
            tb: Self::TABLE.to_string(),
            id: inner_id.into(),
        })
    }

    fn get_inner_string(&self) -> String {
        self.0.id.to_string()
    }
}

Now you can instantiate the UserId type using new, and use it in your struct with SurrealDB like so:

#[derive(Serialize, Deserialize)]
pub struct User {
    id: UserId,
    name: String,
}

// The new function is automatically created for us
// by the blanket implementation from the NewId trait
let typesafe_custom_id = UserId::new("fa77edc3-56ed-4208-9e0b-c0b1c32e2d34").unwrap();

let user_to_be_created = User {
    id: typesafe_custom_id,
    name: "John Doe".to_string(),
};

let db = Surreal::new::<Mem>(()).await.unwrap();
db.use_ns("test").use_db("test").await.unwrap();

let create_result = db.create(USERS_TABLE).content(&user_to_be_created).await;
let retrieved_user: User = create_result.unwrap().remove(0);

assert_eq!(user_to_be_created, retrieved_user)

You also get the following methods on your custom ID type for free:

typesafe_custom_id.table() // returns "users"
typesafe_custom_id.id_with_brackets() // returns "⟨fa77edc3-56ed-4208-9e0b-c0b1c32e2d34⟩"
typesafe_custom_id.id_without_brackets() // returns "fa77edc3-56ed-4208-9e0b-c0b1c32e2d34"

License

Licensed under either of

at your option.

Contribution

Unless 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.

Comments
  • chore: release v0.2.1

    chore: release v0.2.1

    🤖 New release

    • surreal-id: 0.2.0 -> 0.2.1 (✓ API compatible changes)
    Changelog

    0.2.1 - 2023-10-05

    Other

    • Lowering required versions
    • Update docs
    • Bump tonic from 0.10.1 to 0.10.2
    • Bump proptest from 1.2.0 to 1.3.1


    This PR was generated with release-plz.

    opened by liamwh 0
  • Bump proptest from 1.2.0 to 1.3.1

    Bump proptest from 1.2.0 to 1.3.1

    Bumps proptest from 1.2.0 to 1.3.1.

    Commits
    • 0b4ffe8 [Release] 1.3.1 -- fix for incompatible bit-set/bit-vec versions (#375)
    • 99bdf24 [Release] 1.3.0 (#373)
    • 7bfc889 Merge pull request #357 from tzemanovic/tomas/clear-break-dead-code
    • eb9db9d Merge branch 'master' into tomas/clear-break-dead-code
    • 370b3a0 Permit use of (?-u) in byte-regex strategies (#336) (#337)
    • e395e8c Add PathBuf Arbitrary impl with tests (#368)
    • fcccad0 Book tips and best practices (#367)
    • fc3be95 Merge pull request #355 from tzemanovic/tomas/fix-sm-logs
    • 7292965 Merge pull request #360 from psychon/remove-byteorder
    • 466d59d [proptest] silence clippy::arc_with_non_send_sync warning with prop_oneof (#363)
    • Additional commits viewable in compare view

    Dependabot compatibility score

    You can trigger a rebase of this PR by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • Bump thiserror from 1.0.48 to 1.0.49

    Bump thiserror from 1.0.48 to 1.0.49

    Bumps thiserror from 1.0.48 to 1.0.49.

    Release notes

    Sourced from thiserror's releases.

    1.0.49

    • Access libcore types through ::core in generated code (#255, thanks @​mina86)
    Commits

    Dependabot compatibility score

    You can trigger a rebase of this PR by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • Bump tonic from 0.10.1 to 0.10.2

    Bump tonic from 0.10.1 to 0.10.2

    Bumps tonic from 0.10.1 to 0.10.2.

    Changelog

    Sourced from tonic's changelog.

    0.10.2 (2023-09-28)

    Bug Fixes

    • web: Client decoding incomplete buffer bug (#1540) (83e363a)
    Commits

    Dependabot compatibility score

    You can trigger a rebase of this PR by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • chore: release v0.1.1

    chore: release v0.1.1

    🤖 New release

    • surreal-id: 0.1.0 -> 0.1.1 (✓ API compatible changes)
    Changelog

    0.1.1 - 2023-09-22

    Other

    • Loosen interface, additional proptests
    • Improve example
    • Whitespacing
    • Updated readme


    This PR was generated with release-plz.

    opened by liamwh 0
Releases(v0.2.1)
Owner
Liam Woodleigh-Hardinge
A fan of making things secure, fast, reliable, scalable, and well-documented.🦀
Liam Woodleigh-Hardinge
Linked Atomic Random Insert Vector: a thread-safe, self-memory-managed vector with no guaranteed sequential insert.

Linked Atomic Random Insert Vector Lariv is a thread-safe, self-memory-managed vector with no guaranteed sequential insert. It internally uses a linke

Guillem Jara 8 Feb 1, 2023
A query-building & utility crate for SurrealDB and its SQL querying language that aims to be simple

Surreal simple querybuilder A simple query-builder for the Surreal Query Language, for SurrealDB. Aims at being simple to use and not too verbose firs

Thibault H 11 Dec 30, 2022
Custom deserialization for fields that can be specified as multiple types.

serde-this-or-that Custom deserialization for fields that can be specified as multiple types. This crate works with Cargo with a Cargo.toml like: [dep

Ritvik Nag 7 Aug 25, 2022
Manas project aims to create a modular framework and ecosystem to create robust storage servers adhering to Solid protocol in rust.

मनस् | Manas Solid is a web native protocol to enable interoperable, read-write, collaborative, and decentralized web, truer to web's original vision.

Manomayam 17 Oct 5, 2023
probe-run is a custom Cargo runner that transparently runs Rust firmware on an embedded device

probe-run Runs embedded programs just like native ones probe-run is a custom Cargo runner that transparently runs Rust firmware on an embedded device.

Knurling 483 Jan 7, 2023
Custom formatting for Rust.

custom-format This crate extends the standard formatting syntax with custom format specifiers, by providing custom formatting macros. It uses : (a spa

null 6 Dec 14, 2022
Rust library of custom number malarkey, including variable-bit-width integers

Numberwang The Numberwang crate is a library of custom number types and functionality, including variable-bit-width integers. It is named after the fi

Dan Williams 3 Nov 12, 2024
A typemap for a set of known types optionally without heap allocation, and supporting iterating by traits

fixed_typemap docs.rs GitHub Sponsors Implements typemaps that support a lot of extra funcctionality using procedural macros. docs.rs has a lot more t

Austin Hicks 2 Dec 27, 2021
A library for transcoding between bytes in Astro Notation Format and Native Rust data types.

Rust Astro Notation A library for transcoding between hexadecimal strings in Astro Notation Format and Native Rust data types. Usage In your Cargo.tom

Stelar Software 1 Feb 4, 2022
An implementation of a predicative polymorphic language with bidirectional type inference and algebraic data types

Vinilla Lang Vanilla is a pure functional programming language based on System F, a classic but powerful type system. Merits Simple as it is, Vanilla

Zehao Chen 73 Aug 4, 2022
Seamless Higher-Kinded Types in Rust

Seamless Higher-Kinded Types in Rust This is actual working code: pub trait Functor<A> : HKT1 { fn map<B, F: FnMut(A) -> B>(self, f: F) -> Self::W

Massimiliano Tomassoli 55 Jan 22, 2023
Algebraic structures, higher-kinded types and other category theory bad ideas

Algar Algebric structures, higher-kinded types and other category theory bad ideas. Yes, you'll have generalized functors, applicatives, monads, trave

Stefano Candori 3 Jan 31, 2023
Idiomatic Rust implementations for various Windows string types (like UNICODE_STRING)

nt-string by Colin Finck <[email protected]> Provides idiomatic Rust implementations for various Windows string types: NtUnicodeString (with NtUnicode

Colin Finck 5 Jun 4, 2023
Efficiently store Rust idiomatic bytes related types in Avro encoding.

Serde Avro Bytes Avro is a binary encoding format which provides a "bytes" type optimized to store &[u8] data like. Unfortunately the apache_avro enco

Akanoa 3 Mar 30, 2024
Create archives of files within Garry's Mod

gm_zip Create archives of files within Garry's Mod. Note: The scope of this module only works accross the gmod installation files e.g from GarrysMod/g

Earu 9 Oct 25, 2022
Use rust programming language to create a b+ tree.

Use rust programming language to create a b+ tree.

yangshijie 3 Jan 7, 2023
Simple CLI tool to create dummy accounts with referral links to give yourself free Plus.

Free Duolingo Plus A simple CLI tool to create dummy accounts with referral links to give yourself free Plus (max 24/41 weeks depending on whether you

null 23 Apr 27, 2023
My create new project simply (originaly in bash), in rust !

CNPS-Rust CNPS (Create new project simply) is a powerful tool built in Rust that simplifies the process of creating projects in various programming la

Asteroidus 3 Jul 30, 2023