LCOV - code coverage report
Current view: top level - libs/postgres_versioninfo/src - lib.rs (source / functions) Coverage Total Hit
Test: 1e20c4f2b28aa592527961bb32170ebbd2c9172f.info Lines: 51.3 % 78 40
Test Date: 2025-07-16 12:29:03 Functions: 33.3 % 30 10

            Line data    Source code
       1              : use serde::{Deserialize, Deserializer, Serialize, Serializer};
       2              : use serde_repr::{Deserialize_repr, Serialize_repr};
       3              : use std::fmt::{Display, Formatter};
       4              : use std::str::FromStr;
       5              : 
       6              : /// An enum with one variant for each major version of PostgreSQL that we support.
       7              : ///
       8              : #[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Deserialize_repr, Serialize_repr)]
       9              : #[repr(u32)]
      10              : pub enum PgMajorVersion {
      11              :     PG14 = 14,
      12              :     PG15 = 15,
      13              :     PG16 = 16,
      14              :     PG17 = 17,
      15              :     // !!! When you add a new PgMajorVersion, don't forget to update PgMajorVersion::ALL
      16              : }
      17              : 
      18              : /// A full PostgreSQL version ID, in MMmmbb numerical format (Major/minor/bugfix)
      19              : #[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
      20              : #[repr(transparent)]
      21              : pub struct PgVersionId(u32);
      22              : 
      23              : impl PgVersionId {
      24              :     pub const UNKNOWN: PgVersionId = PgVersionId(0);
      25              : 
      26        20319 :     pub fn from_full_pg_version(version: u32) -> PgVersionId {
      27        20319 :         match version {
      28            0 :             0 => PgVersionId(version), // unknown version
      29        20319 :             140000..180000 => PgVersionId(version),
      30            0 :             _ => panic!("Invalid full PostgreSQL version ID {version}"),
      31              :         }
      32        20319 :     }
      33              : }
      34              : 
      35              : impl Display for PgVersionId {
      36            0 :     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
      37            0 :         u32::fmt(&self.0, f)
      38            0 :     }
      39              : }
      40              : 
      41              : impl Serialize for PgVersionId {
      42           54 :     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
      43           54 :     where
      44           54 :         S: Serializer,
      45              :     {
      46           54 :         u32::serialize(&self.0, serializer)
      47            0 :     }
      48              : }
      49              : 
      50              : impl<'de> Deserialize<'de> for PgVersionId {
      51            6 :     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
      52            6 :     where
      53            6 :         D: Deserializer<'de>,
      54              :     {
      55            6 :         u32::deserialize(deserializer).map(PgVersionId)
      56            0 :     }
      57              : 
      58            0 :     fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error>
      59            0 :     where
      60            0 :         D: Deserializer<'de>,
      61              :     {
      62            0 :         u32::deserialize_in_place(deserializer, &mut place.0)
      63            0 :     }
      64              : }
      65              : 
      66              : impl PgMajorVersion {
      67              :     /// Get the numerical representation of the represented Major Version
      68            8 :     pub const fn major_version_num(&self) -> u32 {
      69            8 :         match self {
      70            3 :             PgMajorVersion::PG14 => 14,
      71            0 :             PgMajorVersion::PG15 => 15,
      72            3 :             PgMajorVersion::PG16 => 16,
      73            2 :             PgMajorVersion::PG17 => 17,
      74              :         }
      75            8 :     }
      76              : 
      77              :     /// Get the contents of this version's PG_VERSION file.
      78              :     ///
      79              :     /// The PG_VERSION file is used to determine the PostgreSQL version that currently
      80              :     /// owns the data in a PostgreSQL data directory.
      81            0 :     pub fn versionfile_string(&self) -> &'static str {
      82            0 :         match self {
      83            0 :             PgMajorVersion::PG14 => "14",
      84            0 :             PgMajorVersion::PG15 => "15",
      85            0 :             PgMajorVersion::PG16 => "16\x0A",
      86            0 :             PgMajorVersion::PG17 => "17\x0A",
      87              :         }
      88            0 :     }
      89              : 
      90              :     /// Get the v{version} string of this major PostgreSQL version.
      91              :     ///
      92              :     /// Because this was hand-coded in various places, this was moved into a shared
      93              :     /// implementation.
      94          120 :     pub fn v_str(&self) -> String {
      95          120 :         match self {
      96           33 :             PgMajorVersion::PG14 => "v14",
      97           27 :             PgMajorVersion::PG15 => "v15",
      98           33 :             PgMajorVersion::PG16 => "v16",
      99           27 :             PgMajorVersion::PG17 => "v17",
     100              :         }
     101          120 :         .to_string()
     102          120 :     }
     103              : 
     104              :     /// All currently supported major versions of PostgreSQL.
     105              :     pub const ALL: &'static [PgMajorVersion] = &[
     106              :         PgMajorVersion::PG14,
     107              :         PgMajorVersion::PG15,
     108              :         PgMajorVersion::PG16,
     109              :         PgMajorVersion::PG17,
     110              :     ];
     111              : }
     112              : 
     113              : impl Display for PgMajorVersion {
     114           39 :     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
     115           39 :         f.write_str(match self {
     116           11 :             PgMajorVersion::PG14 => "PgMajorVersion::PG14",
     117            8 :             PgMajorVersion::PG15 => "PgMajorVersion::PG15",
     118           11 :             PgMajorVersion::PG16 => "PgMajorVersion::PG16",
     119            9 :             PgMajorVersion::PG17 => "PgMajorVersion::PG17",
     120              :         })
     121           39 :     }
     122              : }
     123              : 
     124              : #[derive(Debug, thiserror::Error)]
     125              : #[allow(dead_code)]
     126              : pub struct InvalidPgVersion(u32);
     127              : 
     128              : impl Display for InvalidPgVersion {
     129            0 :     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
     130            0 :         write!(f, "InvalidPgVersion({})", self.0)
     131            0 :     }
     132              : }
     133              : 
     134              : impl TryFrom<PgVersionId> for PgMajorVersion {
     135              :     type Error = InvalidPgVersion;
     136              : 
     137        40655 :     fn try_from(value: PgVersionId) -> Result<Self, Self::Error> {
     138        40655 :         Ok(match value.0 / 10000 {
     139            0 :             14 => PgMajorVersion::PG14,
     140            0 :             15 => PgMajorVersion::PG15,
     141            0 :             16 => PgMajorVersion::PG16,
     142        40655 :             17 => PgMajorVersion::PG17,
     143            0 :             _ => return Err(InvalidPgVersion(value.0)),
     144              :         })
     145        40655 :     }
     146              : }
     147              : 
     148              : impl From<PgMajorVersion> for PgVersionId {
     149           14 :     fn from(value: PgMajorVersion) -> Self {
     150           14 :         PgVersionId((value as u32) * 10000)
     151           14 :     }
     152              : }
     153              : 
     154              : #[derive(Debug, PartialEq, Eq, thiserror::Error)]
     155              : pub struct PgMajorVersionParseError(String);
     156              : 
     157              : impl Display for PgMajorVersionParseError {
     158            0 :     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
     159            0 :         write!(f, "PgMajorVersionParseError({})", self.0)
     160            0 :     }
     161              : }
     162              : 
     163              : impl FromStr for PgMajorVersion {
     164              :     type Err = PgMajorVersionParseError;
     165              : 
     166            0 :     fn from_str(s: &str) -> Result<Self, Self::Err> {
     167            0 :         Ok(match s {
     168            0 :             "14" => PgMajorVersion::PG14,
     169            0 :             "15" => PgMajorVersion::PG15,
     170            0 :             "16" => PgMajorVersion::PG16,
     171            0 :             "17" => PgMajorVersion::PG17,
     172            0 :             _ => return Err(PgMajorVersionParseError(s.to_string())),
     173              :         })
     174            0 :     }
     175              : }
        

Generated by: LCOV version 2.1-beta