Id#

The id of a task, link, calendar, resource or assignment. An Id holds a number or a string and compares like a JavaScript object key, so 1 and "1" are the same id. Build one with .into() from a &str, String, f64 or i32 wherever an Id is expected, or name a variant directly.

Declaration#

#[derive(Clone, Debug)]
pub enum Id {
    Num(f64),
    Str(String),
}

impl PartialEq for Id
impl Eq for Id
impl Hash for Id
impl Display for Id
impl From<&str> for Id
impl From<String> for Id
impl From<f64> for Id
impl From<i32> for Id

Id doesn't implement Default, Copy or Ord.

Variants#

Variant Description
Num(f64) Numeric id. Must be finite: a NaN or infinite id in ProjectData fails validation with an InputError of kind Validation, message id must be finite.
Str(String) String id. Any string, including the empty string.

Methods#

key#

pub fn key(&self) -> String

Returns the normalized key: the string a JavaScript engine uses for this id as an object key.

  • Str(s) returns s unchanged.
  • Num(n) returns n formatted the way JavaScript formats a number. Whole numbers print without a fraction (1.0 โ†’ "1"), 0.0 and -0.0 both print "0", and values from 1e21 up or below 1e-6 use exponent notation (1e21 โ†’ "1e+21").

Returns - the normalized key.

norm#

pub fn norm(&self) -> String

Same as key.

Returns - the normalized key.

Equality and hashing#

Two ids are equal when their key values are equal, and equal ids hash the same:

Comparison Result
Id::Num(1.0) == Id::from("1") true
Id::Num(-0.0) == Id::from("0") true
Id::Num(1.5) == Id::from("1.5") true
Id::from("01") == Id::Num(1.0) false (the key of 1.0 is "1")

A HashMap<Id, _> or HashSet<Id> treats 1 and "1" as one key.

Numeric ids keep f64 precision limits. Whole numbers above 2^53 that round to the same f64 are the same id.

Display#

Display writes the key, so format!("{id}") and id.to_string() return the normalized key.

Serialization#

With the serde feature, Id implements Serialize and Deserialize:

  • Str serializes as a JSON string. Num serializes as a JSON integer when it's whole (1.0 โ†’ 1) and as a JSON number otherwise.
  • Serializing a non-finite Num fails with id must be finite.
  • A JSON string deserializes to Str, and any JSON number to Num. Other JSON values fail with the expectation a string or finite number id.
cargo add plen-core --features serde

Example#

use std::collections::HashSet;
use plen_core::Id;

fn main() {
    let a: Id = 1.into();
    let b: Id = "1".into();
    let c = Id::Num(1.5);

    assert_eq!(a, b);
    assert_eq!(a.key(), "1");
    assert_eq!(c.to_string(), "1.5");

    let ids: HashSet<Id> = [a, b, c].into_iter().collect();
    assert_eq!(ids.len(), 2);
}