Skip to main content

PropertyValue

Enum PropertyValue 

Source
pub enum PropertyValue {
Show 13 variants Null, Bool(bool), Int(i64), Float(f64), String(String), Date(i64), Duration { months: i64, days: i64, seconds: i64, nanos: i32, }, LocalTime(i64), Time { nanos_of_day: i64, offset_seconds: i32, }, LocalDateTime { epoch_seconds: i64, nanos: i32, }, DateTime { epoch_seconds: i64, nanos: i32, zone: TzId, }, List(Vec<PropertyValue>), Map(BTreeMap<String, PropertyValue>),
}
Expand description

A node/edge property, as persisted to redb (via postcard, see encode.rs) and used directly as MarsDB’s runtime scalar type – there is no separate “wire” representation. New variants append at the end (postcard’s derive encodes an enum discriminant by declaration order), never reorder/remove an existing one, or every already-stored property silently decodes as the wrong variant.

Date/Duration are Cypher’s DATE/DURATION temporal types, added as first-class variants rather than reusing Int/String – e.g. stashing a date as Int(epoch_day) would round-trip through storage fine, but a plain Int and a Date would then be indistinguishable once read back (Temporal4’s “store a date, read it back, it must still print/compare/access-components as a date” scenarios need that distinction to survive the storage boundary). LocalTime/Time/ LocalDateTime/DateTime (Cypher’s other four temporal types) follow the same reasoning below. Time only accepts a fixed UTC offset – it carries no calendar date, so a named zone’s DST-dependent offset has nothing to resolve against; DateTime accepts either a fixed offset or a named zone (TzId).

Map exists here for exactly one reason: a $parameter’s value can be map-shaped ({name: 'Apa'}, TCK’s Map2/Map3), and query-time parameters flow in as PropertyValue (this is the one place a non-storable shape has to travel through). A node/edge property value is never actually a Map though – real Cypher forbids storing one (marsdb-query::executor::value_to_storable_property rejects it outright before anything reaches GraphStore), so this variant is only ever constructed on the parameter-passing path, never persisted.

Variants§

§

Null

§

Bool(bool)

§

Int(i64)

§

Float(f64)

§

String(String)

§

Date(i64)

A calendar date with no time-of-day or timezone, stored as the number of days since the Unix epoch (1970-01-01), proleptic Gregorian. Plain i32 (not a chrono type) – keeps this crate’s storage format independent of any date library’s own internal representation (which is free to change across chrono versions), and keeps comparison a plain integer compare. Conversion to/from calendar year/month/day and ISO-8601 text lives in marsdb-query (temporal.rs), not here – this crate only stores the value, it doesn’t know Cypher’s date grammar/semantics. i64, not i32: Cypher’s full year range (±999_999_999, ISO 8601 expanded years) reaches ±365 billion epoch days, past i32. Wire-compatible with values written as i32: postcard varints don’t encode the width, and the index key encoding was already 8-byte (see index.rs).

§

Duration

An ISO-8601 duration (Cypher’s DURATION type), kept in Neo4j’s own four-component normalized form rather than as a single scalar – months and days are not fungible with each other or with seconds (a month is 28-31 days depending which month; without a reference date, “3 months” has no fixed length in days at all), so collapsing duration({months: 1}) and duration({days: 30}) into one comparable number would silently be wrong once added to some starting date. nanos always has the same sign as seconds (or is 0) – i.e. seconds*1_000_000_000 + nanos is total_nanoseconds truncated-towards-zero the same way Rust’s integer division/% already works, never a separately-signed remainder – so “-1.999 seconds” is seconds: -1, nanos: -999_000_000, not seconds: -2, nanos: 1_000_000, which would make the same duration representable two different ways.

Fields

§months: i64
§days: i64
§seconds: i64
§nanos: i32
§

LocalTime(i64)

A time-of-day with no date or timezone, stored as nanoseconds since midnight (0..86_400_000_000_000, always non-negative – there’s no sign to carry the way Date’s epoch-day has). Cypher’s LOCAL TIME.

§

Time

A time-of-day with a fixed UTC offset (Cypher’s TIME) – named timezones (Europe/Stockholm) aren’t supported, only literal +HH:MM-style offsets (see marsdb-query::temporal’s module docs for the exact scope). nanos_of_day is the wall-clock reading (same representation as LocalTime); offset_seconds is seconds east of UTC. Comparison/equality use the UTC-equivalent instant-of-day (nanos_of_day - offset_seconds), not the raw wall-clock reading – two Times at different offsets can represent the same instant.

Fields

§nanos_of_day: i64
§offset_seconds: i32
§

LocalDateTime

A calendar date + time-of-day with no timezone (Cypher’s LOCAL DATETIME), stored as a naive (zone-less) instant: whole seconds since the Unix epoch (epoch_seconds, signed – a pre-1970 value is negative) plus a 0..999_999_999 nanosecond remainder that always stays non-negative (the sign lives entirely in epoch_seconds, mirroring Duration’s “no separately-signed remainder” invariant).

Fields

§epoch_seconds: i64
§nanos: i32
§

DateTime

A calendar date + time-of-day with a timezone (Cypher’s DATETIME) – either a fixed UTC offset or a named IANA zone (Europe/Stockholm). epoch_seconds/nanos are the UTC instant (same convention as LocalDateTime); zone is kept only for display/round-tripping the original wall-clock reading – comparison/equality use the instant alone, matching real Cypher (two DateTimes at the same instant but different zones are equal, even though they print differently). A Named zone’s real offset at this instant is not cached here (the same zone has different offsets across a DST transition) – it’s re-derived on demand via chrono-tz (marsdb-query::temporal::resolve_ offset), this crate only stores the value, it doesn’t know Cypher’s timezone-resolution semantics.

Fields

§epoch_seconds: i64
§nanos: i32
§zone: TzId
§

List(Vec<PropertyValue>)

A homogeneous array of scalars (real Cypher/Neo4j’s own property restriction: a stored list property can hold any of the scalar variants above, all the same variant, never Null-mixed-with-a- type, another List, or a map – enforced where a Value::List is converted to a storable PropertyValue, in marsdb-query, not here; this crate just stores whatever Vec<PropertyValue> it’s given). Appended last (see this enum’s own doc comment on why variant order is a real, one-way storage-compat constraint).

§

Map(BTreeMap<String, PropertyValue>)

See this enum’s own doc comment – parameter-passing only, never a real stored property value.

Trait Implementations§

Source§

impl Clone for PropertyValue

Source§

fn clone(&self) -> PropertyValue

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for PropertyValue

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for PropertyValue

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl PartialEq for PropertyValue

Source§

fn eq(&self, other: &PropertyValue) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl Serialize for PropertyValue

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for PropertyValue

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.