rupg-types 0.1.84

The value model, Datum, Vector of 1024 values, TypeId, the text and binary forms of the 197 types, numeric, date and time, JSON, arrays, ranges.
Documentation
//! `Value`, one value of any type in the engine.
//!
//! A value does not carry its type. The expression that gives the value has the type OID and the typmod, as a `Datum` of PostgreSQL has no type and the plan node has it. So one variant holds the values of many types: `Text` holds `text`, `name`, `varchar`, `bpchar`, `unknown` and the other types whose value is a string, and `Oid` holds `oid`, `xid`, `cid` and the OID alias types such as `regclass`. [`Datum`](crate::Datum) is the value of the M1 storage, which stores fewer types.

use std::sync::Arc;

use crate::array::Array;
use crate::datetime::Interval;
use crate::jsonpath::JsonPath;
use crate::network::Inet;
use crate::numeric::Numeric;
use crate::range::Range;
use crate::tsquery::QueryItem;
use crate::tsvector::Lexeme;

/// One value of the engine.
#[derive(Clone, Debug, PartialEq)]
pub enum Value {
    /// SQL NULL.
    Null,
    Bool(bool),
    Int2(i16),
    Int4(i32),
    Int8(i64),
    Float4(f32),
    Float8(f64),
    Numeric(Numeric),
    /// `oid`, `xid`, `cid` and the OID alias types.
    Oid(u32),
    /// The type `"char"`. The byte 0 is the empty string.
    Char(u8),
    /// The string types, `unknown`, `cstring`, `json` and the other types that the engine keeps as their text form.
    Text(String),
    Bytea(Vec<u8>),
    Uuid([u8; 16]),
    /// `date`, the days since 1 January 2000.
    Date(i32),
    /// `time`, the microseconds since midnight.
    Time(i64),
    /// `timetz`, the microseconds since midnight and the zone offset in seconds west of UTC.
    TimeTz(i64, i32),
    /// `timestamp`, the microseconds since 1 January 2000.
    Timestamp(i64),
    /// `timestamptz`, the microseconds since 1 January 2000 UTC.
    TimestampTz(i64),
    Interval(Interval),
    /// `inet` and `cidr`.
    Inet(Inet),
    /// An array, `int2vector` or `oidvector`. A null element is `None`, and no element is `Some(Value::Null)`.
    Array(Box<Array<Value>>),
    /// A row of a composite type or of `record`.
    Record(Box<Record>),
    /// A value of a range type.
    Range(Box<Range>),
    /// A value of a multirange type: the ranges in order, with no empty range and no two ranges that overlap or touch.
    Multirange(Vec<Range>),
    /// A value of `tsvector`: the lexemes in order.
    TsVector(Vec<Lexeme>),
    /// A value of `tsquery`: the operands and operators in prefix order, or no items for a query with no lexemes.
    TsQuery(Vec<QueryItem>),
    /// A value of `jsonpath`.
    JsonPath(Box<JsonPath>),
}

/// The value of a composite type or of `record`, as a `HeapTupleHeader` datum. As that datum keeps the type of the row, a record keeps the type of each field, so that the output of an anonymous `record` can show the fields.
#[derive(Clone, Debug)]
pub struct Record {
    /// The type of each field.
    pub types: Vec<u32>,
    /// The value of each field, with `Null` for a null field.
    pub values: Vec<Value>,
    /// The names of the fields of an anonymous `record`, as the row descriptor that `BlessTupleDesc` keeps for the typmod of the value. `None` when the type of the value gives the names, or when the fields are `f1`, `f2` and so on.
    pub names: Option<Arc<[String]>>,
}

impl Record {
    /// A record with no names for its fields.
    pub fn new(types: Vec<u32>, values: Vec<Value>) -> Record {
        Record { types, values, names: None }
    }
}

/// Two records are equal when their fields are equal. The names of the fields are not part of the value.
impl PartialEq for Record {
    fn eq(&self, other: &Record) -> bool {
        self.types == other.types && self.values == other.values
    }
}

impl Value {
    /// True for `Null`.
    pub fn is_null(&self) -> bool {
        matches!(self, Value::Null)
    }

    /// The value of a `bool`, or `None` for `Null`.
    pub fn as_bool(&self) -> Option<bool> {
        match self {
            Value::Bool(v) => Some(*v),
            _ => None,
        }
    }

    /// The string of a value of a string type, or `None` for `Null`.
    pub fn as_str(&self) -> Option<&str> {
        match self {
            Value::Text(v) => Some(v),
            _ => None,
        }
    }

    /// The value of an integer type as an `i64`, or `None` for `Null` and for the other types.
    pub fn as_i64(&self) -> Option<i64> {
        match self {
            Value::Int2(v) => Some(i64::from(*v)),
            Value::Int4(v) => Some(i64::from(*v)),
            Value::Int8(v) => Some(*v),
            _ => None,
        }
    }

    /// The value of `oid` or of an OID alias type, or `None` for `Null`.
    pub fn as_oid(&self) -> Option<u32> {
        match self {
            Value::Oid(v) => Some(*v),
            _ => None,
        }
    }

    /// A text value.
    pub fn text(s: impl Into<String>) -> Value {
        Value::Text(s.into())
    }
}