Skip to main content

rupg_types/
typeid.rs

1//! The type ids of the M1 types (spec/07 section 7.9).
2
3use std::fmt;
4
5use rupg_common::Oid;
6
7/// A type, by its OID in `pg_type` of the PostgreSQL pin.
8#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
9pub struct TypeId(pub Oid);
10
11impl TypeId {
12    /// `bool`.
13    pub const BOOL: TypeId = TypeId(Oid(16));
14    /// `bytea`.
15    pub const BYTEA: TypeId = TypeId(Oid(17));
16    /// `int8`.
17    pub const INT8: TypeId = TypeId(Oid(20));
18    /// `int2`.
19    pub const INT2: TypeId = TypeId(Oid(21));
20    /// `int4`.
21    pub const INT4: TypeId = TypeId(Oid(23));
22    /// `text`.
23    pub const TEXT: TypeId = TypeId(Oid(25));
24    /// `oid`.
25    pub const OID: TypeId = TypeId(Oid(26));
26    /// `float4`.
27    pub const FLOAT4: TypeId = TypeId(Oid(700));
28    /// `float8`.
29    pub const FLOAT8: TypeId = TypeId(Oid(701));
30    /// `date`.
31    pub const DATE: TypeId = TypeId(Oid(1082));
32    /// `timestamp`.
33    pub const TIMESTAMP: TypeId = TypeId(Oid(1114));
34    /// `timestamptz`.
35    pub const TIMESTAMPTZ: TypeId = TypeId(Oid(1184));
36    /// `uuid`.
37    pub const UUID: TypeId = TypeId(Oid(2950));
38
39    /// The types that M1 stores. Later milestones add the other types of the pin.
40    pub const M1: [TypeId; 13] = [
41        TypeId::BOOL,
42        TypeId::BYTEA,
43        TypeId::INT8,
44        TypeId::INT2,
45        TypeId::INT4,
46        TypeId::TEXT,
47        TypeId::OID,
48        TypeId::FLOAT4,
49        TypeId::FLOAT8,
50        TypeId::DATE,
51        TypeId::TIMESTAMP,
52        TypeId::TIMESTAMPTZ,
53        TypeId::UUID,
54    ];
55
56    /// The type with this OID, or `None` if M1 does not store it.
57    pub fn from_oid(oid: Oid) -> Option<TypeId> {
58        TypeId::M1.into_iter().find(|t| t.0 == oid)
59    }
60
61    /// The name in `pg_type`.
62    pub fn name(self) -> &'static str {
63        match self {
64            TypeId::BOOL => "bool",
65            TypeId::BYTEA => "bytea",
66            TypeId::INT8 => "int8",
67            TypeId::INT2 => "int2",
68            TypeId::INT4 => "int4",
69            TypeId::TEXT => "text",
70            TypeId::OID => "oid",
71            TypeId::FLOAT4 => "float4",
72            TypeId::FLOAT8 => "float8",
73            TypeId::DATE => "date",
74            TypeId::TIMESTAMP => "timestamp",
75            TypeId::TIMESTAMPTZ => "timestamptz",
76            TypeId::UUID => "uuid",
77            _ => "unknown",
78        }
79    }
80
81    /// The name that PostgreSQL gives in messages, from `format_type_be`.
82    pub fn sql_name(self) -> &'static str {
83        match self {
84            TypeId::BOOL => "boolean",
85            TypeId::INT8 => "bigint",
86            TypeId::INT2 => "smallint",
87            TypeId::INT4 => "integer",
88            TypeId::FLOAT4 => "real",
89            TypeId::FLOAT8 => "double precision",
90            TypeId::TIMESTAMP => "timestamp without time zone",
91            TypeId::TIMESTAMPTZ => "timestamp with time zone",
92            other => other.name(),
93        }
94    }
95
96    /// The bytes of a value in storage form, or `None` for a type whose values have their own length.
97    pub fn width(self) -> Option<u8> {
98        match self {
99            TypeId::BOOL => Some(1),
100            TypeId::INT2 => Some(2),
101            TypeId::INT4 | TypeId::OID | TypeId::FLOAT4 | TypeId::DATE => Some(4),
102            TypeId::INT8 | TypeId::FLOAT8 | TypeId::TIMESTAMP | TypeId::TIMESTAMPTZ => Some(8),
103            TypeId::UUID => Some(16),
104            _ => None,
105        }
106    }
107}
108
109impl fmt::Display for TypeId {
110    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111        f.write_str(self.name())
112    }
113}