ronantakizawa/codereview-bench huggingface dataset:
Repository: launchbadge/sqlx
File: sqlx-core/src/from_row.rs (Rust)

Code before:
/// if the field type has an implementation for [`Default`],
/// you can use the `default` attribute to assign the default value to said field.
/// For example:
///
/// ```rust,ignore
/// #[derive(sqlx::FromRow)]
/// struct User {
///     id: i32,
///     name: String,
///     #[sqlx(default)]
///     location: Option<String>
/// }
/// ```
///
/// Given a query such as:
///
/// ```sql
/// SELECT id, name FROM users;
/// ```
///
/// will set the value of the field `location` to the default value of `Option<String>`,
/// which is `None`.
///
/// ## Manual implementation
///
/// You can also implement the [`FromRow`] trait by hand. This can be useful, if you
/// have a struct with a field that needs manuel decoding:
///
/// ```rust,ignore
/// # use sqlx_core::from_row::FromRow;
/// # use sqlx_core::error::Result;
/// # use sqlx_core::sqlite::{SqliteRow};
/// # use crate::sqlx_core::row::Row;
///
/// struct MyCustomType {
///     custom: String,
/// }
///
/// struct Foo {
///     bar: MyCustomType,
/// }
///
/// impl FromRow<'_, SqliteRow> for Foo {
///     fn from_row(row: &SqliteRow) -> Result<Self> {
///         Ok(Self {
///             bar: MyCustomType {
///                 custom: row.try_get("custom")?
///             }
///         })
///     }
/// }

Review comment (suggestion):
```suggestion
/// You can also implement the [`FromRow`] trait by hand. This can be useful if you
```

Code after:
/// if the field type has an implementation for [`Default`],
/// you can use the `default` attribute to assign the default value to said field.
/// For example:
///
/// ```rust,ignore
/// #[derive(sqlx::FromRow)]
/// struct User {
///     id: i32,
///     name: String,
///     #[sqlx(default)]
///     location: Option<String>
/// }
/// ```
///
/// Given a query such as:
///
/// ```sql
/// SELECT id, name FROM users;
/// ```
///
/// will set the value of the field `location` to the default value of `Option<String>`,
/// which is `None`.
///
/// ### `flatten`
///
/// If you want to handle a field that implements [`FromRow`],
/// you can use the `flatten` attribute to specify that you want
/// it to use [`FromRow`] for parsing rather than the usual method.
/// For example:
///
/// ```rust,ignore
/// #[derive(sqlx::FromRow)]
/// struct Address {
///     country: String,
///     city: String,
///     road: String,
/// }
///
/// #[derive(sqlx::FromRow)]
/// struct User {
///     id: i32,
///     name: String,
///     #[sqlx(flatten)]
///     address: Address,
/// }
/// ```
/// Given a query such as:
///
/// ```sql
/// SELECT id, name, country, city, road FROM users;
/// ```
Repository: launchbadge/sqlx
File: sqlx-core/src/from_row.rs (Rust)

Code before:
///     id: i32,
///     name: String,
///     #[sqlx(default)]
///     location: Option<String>
/// }
/// ```
///
/// Given a query such as:
///
/// ```sql
/// SELECT id, name FROM users;
/// ```
///
/// will set the value of the field `location` to the default value of `Option<String>`,
/// which is `None`.
///
/// ## Manual implementation
///
/// You can also implement the [`FromRow`] trait by hand. This can be useful if you
/// have a struct with a field that needs manuel decoding:
///
/// ```rust,ignore
/// # use sqlx_core::from_row::FromRow;
/// # use sqlx_core::error::Result;
/// # use sqlx_core::sqlite::{SqliteRow};
/// # use crate::sqlx_core::row::Row;
///
/// struct MyCustomType {
///     custom: String,
/// }
///
/// struct Foo {
///     bar: MyCustomType,
/// }
///
/// impl FromRow<'_, SqliteRow> for Foo {
///     fn from_row(row: &SqliteRow) -> Result<Self> {
///         Ok(Self {
///             bar: MyCustomType {
///                 custom: row.try_get("custom")?
///             }
///         })
///     }
/// }
/// ```
///
pub trait FromRow<'r, R: Row>: Sized {
    fn from_row(row: &'r R) -> Result<Self, Error>;
}

// implement FromRow for tuples of types that implement Decode

Review comment (suggestion):
Even though this is in `sqlx-core`, since it's not built anyway I would prefer if it used these items as exported from the `sqlx` crate, as `sqlx-core` is not really meant to be used directly.

Code after:
///     id: i32,
///     name: String,
///     #[sqlx(default)]
///     location: Option<String>
/// }
/// ```
///
/// Given a query such as:
///
/// ```sql
/// SELECT id, name FROM users;
/// ```
///
/// will set the value of the field `location` to the default value of `Option<String>`,
/// which is `None`.
///
/// ### `flatten`
///
/// If you want to handle a field that implements [`FromRow`],
/// you can use the `flatten` attribute to specify that you want
/// it to use [`FromRow`] for parsing rather than the usual method.
/// For example:
///
/// ```rust,ignore
/// #[derive(sqlx::FromRow)]
/// struct Address {
///     country: String,
///     city: String,
///     road: String,
/// }
///
/// #[derive(sqlx::FromRow)]
/// struct User {
///     id: i32,
///     name: String,
///     #[sqlx(flatten)]
///     address: Address,
/// }
/// ```
/// Given a query such as:
///
/// ```sql
/// SELECT id, name, country, city, road FROM users;
/// ```
///
/// This field is compatible with the `default` attribute.
///
/// ## Manual implementation
///
/// You can also implement the [`FromRow`] trait by hand. This can be useful if you
/// have a struct with a field that needs manuel decoding:
Repository: launchbadge/sqlx
File: sqlx-core/src/from_row.rs (Rust)

Code before:
/// struct User {
///     id: i32,
///     name: String,
///     #[sqlx(default)]
///     location: Option<String>
/// }
/// ```
///
/// Given a query such as:
///
/// ```sql
/// SELECT id, name FROM users;
/// ```
///
/// will set the value of the field `location` to the default value of `Option<String>`,
/// which is `None`.
///
/// ## Manual implementation
///
/// You can also implement the [`FromRow`] trait by hand. This can be useful if you
/// have a struct with a field that needs manuel decoding:
///
/// ```rust
/// # extern crate sqlx;
/// use sqlx::FromRow;
/// use sqlx::error::Result;
/// use sqlx::sqlite::SqliteRow;
/// use sqlx::Row;
///
/// struct MyCustomType {
///     custom: String,
/// }
///
/// struct Foo {
///     bar: MyCustomType,
/// }
///
/// impl FromRow<'_, SqliteRow> for Foo {
///     fn from_row(row: &SqliteRow) -> Result<Self> {
///         Ok(Self {
///             bar: MyCustomType {
///                 custom: row.try_get("custom")?
///             }
///         })
///     }
/// }
/// ```
///
pub trait FromRow<'r, R: Row>: Sized {
    fn from_row(row: &'r R) -> Result<Self, Error>;
}

Review comment (suggestion):
We prefer that people use `sqlx::Result<...>` to make it clearer why `Result` only has one type parameter when you'd normally expect to see two.

Code after:
/// struct User {
///     id: i32,
///     name: String,
///     #[sqlx(default)]
///     location: Option<String>
/// }
/// ```
///
/// Given a query such as:
///
/// ```sql
/// SELECT id, name FROM users;
/// ```
///
/// will set the value of the field `location` to the default value of `Option<String>`,
/// which is `None`.
///
/// ### `flatten`
///
/// If you want to handle a field that implements [`FromRow`],
/// you can use the `flatten` attribute to specify that you want
/// it to use [`FromRow`] for parsing rather than the usual method.
/// For example:
///
/// ```rust,ignore
/// #[derive(sqlx::FromRow)]
/// struct Address {
///     country: String,
///     city: String,
///     road: String,
/// }
///
/// #[derive(sqlx::FromRow)]
/// struct User {
///     id: i32,
///     name: String,
///     #[sqlx(flatten)]
///     address: Address,
/// }
/// ```
/// Given a query such as:
///
/// ```sql
/// SELECT id, name, country, city, road FROM users;
/// ```
///
/// This field is compatible with the `default` attribute.
///
/// ## Manual implementation
///
/// You can also implement the [`FromRow`] trait by hand. This can be useful if you
Repository: launchbadge/sqlx
File: sqlx-macros/src/database/postgres.rs (Rust)

Code before:
use sqlx_core as sqlx;

impl_database_ext! {
    sqlx::postgres::Postgres {
        (),
        bool,
        String | &str,
        i8,
        i16,
        i32,
        sqlx::postgres::types::Oid,
        i64,
        f32,
        f64,
        Vec<u8> | &[u8],

        sqlx::postgres::types::PgInterval,

        sqlx::postgres::types::PgMoney,

        #[cfg(feature = "uuid")]
        sqlx::types::Uuid,

        #[cfg(feature = "chrono")]
        sqlx::types::chrono::NaiveTime,

        #[cfg(feature = "chrono")]
        sqlx::types::chrono::NaiveDate,

        #[cfg(feature = "chrono")]
        sqlx::types::chrono::NaiveDateTime,

        #[cfg(feature = "chrono")]
        sqlx::types::chrono::DateTime<sqlx::types::chrono::Utc> | sqlx::types::chrono::DateTime<_>,

        #[cfg(feature = "chrono")]

Review comment (suggestion):
As a styling nit, this should be sorted with the other `Pg___` types below rather than stuck in the middle of a list of primitives.

Code after:
use sqlx_core as sqlx;

impl_database_ext! {
    sqlx::postgres::Postgres {
        (),
        bool,
        String | &str,
        i8,
        i16,
        i32,
        i64,
        f32,
        f64,
        Vec<u8> | &[u8],

        sqlx::postgres::types::Oid,

        sqlx::postgres::types::PgInterval,

        sqlx::postgres::types::PgMoney,

        sqlx::postgres::types::PgLTree,

        sqlx::postgres::types::PgLQuery,

        #[cfg(feature = "uuid")]
        sqlx::types::Uuid,

        #[cfg(feature = "chrono")]
        sqlx::types::chrono::NaiveTime,

        #[cfg(feature = "chrono")]
        sqlx::types::chrono::NaiveDate,

        #[cfg(feature = "chrono")]
        sqlx::types::chrono::NaiveDateTime,
Repository: launchbadge/sqlx
File: sqlx-core/src/postgres/types/ltree.rs (Rust)

Code before:
    }
}

impl FromStr for PgLTree {
    type Err = Error;

    fn from_str(s: &str) -> Result<Self, Error> {
        Ok(
            Self {
                labels: s.split('.').map(|s| s.to_owned()).collect()
            }
        )
    }
}

impl Display for PgLTree {
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.labels.join("."))
    }
}

impl Type<Postgres> for PgLTree {
    fn type_info() -> PgTypeInfo {
        PgTypeInfo::LTREE
    }
}

impl Encode<'_, Postgres> for PgLTree {
    fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> IsNull {
        buf.extend(1i8.to_le_bytes());
        buf.extend(self.to_string().as_bytes());

        IsNull::No
    }
}

impl<'r> Decode<'r, Postgres> for PgLTree {
    fn decode(value: PgValueRef<'r>) -> Result<Self, BoxDynError> {
        match value.format() {
            PgValueFormat::Binary => {
                let bytes = value.as_bytes()?;
                let version = i8::from_le_bytes([bytes[0]; 1]);
                if version != 1 {
                    todo!("add error here")
                }
                Ok(Self::from_str(&String::from_utf8(bytes[1..].to_vec())?)?)
            },
            PgValueFormat::Text => Ok(Self::from_str(value.as_str()?)?)
        }
    }
}

Review comment (suggestion):
I'm wondering if should push this as separate crate. It seems it could ease the work that i want to put in sea-orm

Code after:
    #[error("ltree version not supported")]
    InvalidLtreeVersion,
}

/// Container for a Label Tree (`ltree`) in Postgres.
///
/// See https://www.postgresql.org/docs/current/ltree.html
///
/// ### Note: Requires Postgres 13+
///
/// This integration requires that the `ltree` type support the binary format in the Postgres
/// wire protocol, which only became available in Postgres 13.
/// ([Postgres 13.0 Release Notes, Additional Modules][https://www.postgresql.org/docs/13/release-13.html#id-1.11.6.11.5.14])
///
/// Ideally, SQLx's Postgres driver should support falling back to text format for types
/// which don't have `typsend` and `typrecv` entries in `pg_type`, but that work still needs
/// to be done.
///
/// ### Note: Extension Required
/// The `ltree` extension is not enabled by default in Postgres. You will need to do so explicitly:
///
/// ```ignore
/// CREATE EXTENSION IF NOT EXISTS "ltree";
/// ```
#[derive(Clone, Debug, Default, PartialEq)]
pub struct PgLTree {
    labels: Vec<String>,
}

impl PgLTree {
    /// creates default/empty ltree
    pub fn new() -> Self {
        Self::default()
    }

    /// creates ltree from a [Vec<String>] without checking labels
    pub fn new_unchecked(labels: Vec<String>) -> Self {
        Self { labels }
    }

    /// creates ltree from an iterator with checking labels
    pub fn from_iter<I, S>(labels: I) -> Result<Self, PgLTreeParseError>
    where
        S: Into<String>,
        I: IntoIterator<Item = S>,
    {
        let mut ltree = Self::default();
        for label in labels {
            ltree.push(label.into())?;
        }
        Ok(ltree)
Repository: launchbadge/sqlx
File: sqlx-core/src/postgres/types/ltree.rs (Rust)

Code before:

impl Type<Postgres> for PgLTree {
    fn type_info() -> PgTypeInfo {
        PgTypeInfo::LTREE
    }
}

impl Encode<'_, Postgres> for PgLTree {
    fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> IsNull {
        buf.extend(1i8.to_le_bytes());
        buf.extend(self.to_string().as_bytes());

        IsNull::No
    }
}

impl<'r> Decode<'r, Postgres> for PgLTree {
    fn decode(value: PgValueRef<'r>) -> Result<Self, BoxDynError> {
        match value.format() {
            PgValueFormat::Binary => {
                let bytes = value.as_bytes()?;
                let version = i8::from_le_bytes([bytes[0]; 1]);
                if version != 1 {
                    todo!("add error here")
                }
                Ok(Self::from_str(&String::from_utf8(bytes[1..].to_vec())?)?)
            },
            PgValueFormat::Text => Ok(Self::from_str(value.as_str()?)?)
        }
    }
}


Review comment (suggestion):
Could we avoid this allocation by replacing `String` with `std::str` and removing the `.to_vec()`

Code after:
///
/// ```ignore
/// CREATE EXTENSION IF NOT EXISTS "ltree";
/// ```
#[derive(Clone, Debug, Default, PartialEq)]
pub struct PgLTree {
    labels: Vec<String>,
}

impl PgLTree {
    /// creates default/empty ltree
    pub fn new() -> Self {
        Self::default()
    }

    /// creates ltree from a [Vec<String>] without checking labels
    pub fn new_unchecked(labels: Vec<String>) -> Self {
        Self { labels }
    }

    /// creates ltree from an iterator with checking labels
    pub fn from_iter<I, S>(labels: I) -> Result<Self, PgLTreeParseError>
    where
        S: Into<String>,
        I: IntoIterator<Item = S>,
    {
        let mut ltree = Self::default();
        for label in labels {
            ltree.push(label.into())?;
        }
        Ok(ltree)
    }

    /// push a label to ltree
    pub fn push(&mut self, label: String) -> Result<(), PgLTreeParseError> {
        if label.len() <= 256
            && label
                .bytes()
                .all(|c| c.is_ascii_alphabetic() || c.is_ascii_digit() || c == b'_')
        {
            self.labels.push(label);
            Ok(())
        } else {
            Err(PgLTreeParseError::InvalidLtreeLabel)
        }
    }

    /// pop a label from ltree
    pub fn pop(&mut self) -> Option<String> {
        self.labels.pop()
    }
Repository: launchbadge/sqlx
File: sqlx-core/src/postgres/types/ltree.rs (Rust)

Code before:
use std::fmt::{self, Display, Formatter};
use std::str::FromStr;
use crate::decode::Decode;
use crate::encode::{Encode, IsNull};
use crate::error::{Error, BoxDynError};
use crate::postgres::{PgArgumentBuffer, PgValueFormat, PgTypeInfo, PgValueRef, Postgres};
use crate::types::Type;

#[derive(Clone, Debug, Default, PartialEq)]
pub struct PgLTree {
    labels: Vec<String>
}

impl PgLTree {
    pub fn push(&mut self, label: String) -> Result<(), Error> {
        if label.chars().all(|c| c.is_ascii_alphabetic() || c.is_ascii_digit() || c == '_') {
            self.labels.push(label);
            Ok(())
        } else {
            Err(Error::InvalidLtreeLabel)
        }
    }
}

impl FromStr for PgLTree {
    type Err = Error;

    fn from_str(s: &str) -> Result<Self, Error> {
        Ok(
            Self {
                labels: s.split('.').map(|s| s.to_owned()).collect()
            }
        )
    }
}

impl Display for PgLTree {
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.labels.join("."))
    }
}

Review comment (suggestion):
Since every byte of the string is expected to be ascii this would be faster if we replaced `chars` with `bytes`

Code after:
use crate::decode::Decode;
use crate::encode::{Encode, IsNull};
use crate::error::BoxDynError;
use crate::postgres::{
    PgArgumentBuffer, PgHasArrayType, PgTypeInfo, PgValueFormat, PgValueRef, Postgres,
};
use crate::types::Type;
use std::fmt::{self, Display, Formatter};
use std::io::Write;
use std::ops::Deref;
use std::str::FromStr;

/// Represents ltree specific errors
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum PgLTreeParseError {
    /// LTree labels can only contain [A-Za-z0-9_]
    #[error("ltree label cotains invalid characters")]
    InvalidLtreeLabel,

    /// LTree version not supported
    #[error("ltree version not supported")]
    InvalidLtreeVersion,
}

/// Container for a Label Tree (`ltree`) in Postgres.
///
/// See https://www.postgresql.org/docs/current/ltree.html
///
/// ### Note: Requires Postgres 13+
///
/// This integration requires that the `ltree` type support the binary format in the Postgres
/// wire protocol, which only became available in Postgres 13.
/// ([Postgres 13.0 Release Notes, Additional Modules][https://www.postgresql.org/docs/13/release-13.html#id-1.11.6.11.5.14])
///
/// Ideally, SQLx's Postgres driver should support falling back to text format for types
/// which don't have `typsend` and `typrecv` entries in `pg_type`, but that work still needs
/// to be done.
///
/// ### Note: Extension Required
/// The `ltree` extension is not enabled by default in Postgres. You will need to do so explicitly:
Repository: launchbadge/sqlx
File: sqlx-core/src/postgres/types/ltree.rs (Rust)

Code before:
use std::fmt::{self, Display, Formatter};
use std::str::FromStr;


/// Represents ltree specific errors
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum Error {
   /// LTree labels can only contain [A-Za-z0-9_]
    #[error("ltree label cotains invalid characters")]
    InvalidLtreeLabel,

    /// LTree version not supported
    #[error("ltree version not supported")]
    InvalidLtreeVersion,
}


/// Represents an postgres ltree. Not that this is an EXTENSION!
#[derive(Clone, Debug, Default, PartialEq)]
pub struct PgLTree {
    labels: Vec<String>,
}

impl PgLTree {
    pub fn push(&mut self, label: String) -> Result<(), Error> {
        if label
            .bytes()
            .all(|c| c.is_ascii_alphabetic() || c.is_ascii_digit() || c == b'_')
        {
            self.labels.push(label);
            Ok(())
        } else {
            Err(Error::InvalidLtreeLabel)
        }
    }

    pub fn pop(&mut self) -> Option<String> {
        self.labels.pop()
    }
}

impl FromStr for PgLTree {
    type Err = Error;

    fn from_str(s: &str) -> Result<Self, Error> {
        Ok(Self {
            labels: s.split('.').map(|s| s.to_owned()).collect(),
        })
    }
}

Review comment (suggestion):
Now that I think of it there should also be a `new` method, otherwise there's no ergonomic way of building an ltree from scratch.

Code after:
};
use crate::types::Type;
use std::fmt::{self, Display, Formatter};
use std::io::Write;
use std::ops::Deref;
use std::str::FromStr;

/// Represents ltree specific errors
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum PgLTreeParseError {
    /// LTree labels can only contain [A-Za-z0-9_]
    #[error("ltree label cotains invalid characters")]
    InvalidLtreeLabel,

    /// LTree version not supported
    #[error("ltree version not supported")]
    InvalidLtreeVersion,
}

/// Container for a Label Tree (`ltree`) in Postgres.
///
/// See https://www.postgresql.org/docs/current/ltree.html
///
/// ### Note: Requires Postgres 13+
///
/// This integration requires that the `ltree` type support the binary format in the Postgres
/// wire protocol, which only became available in Postgres 13.
/// ([Postgres 13.0 Release Notes, Additional Modules][https://www.postgresql.org/docs/13/release-13.html#id-1.11.6.11.5.14])
///
/// Ideally, SQLx's Postgres driver should support falling back to text format for types
/// which don't have `typsend` and `typrecv` entries in `pg_type`, but that work still needs
/// to be done.
///
/// ### Note: Extension Required
/// The `ltree` extension is not enabled by default in Postgres. You will need to do so explicitly:
///
/// ```ignore
/// CREATE EXTENSION IF NOT EXISTS "ltree";
/// ```
#[derive(Clone, Debug, Default, PartialEq)]
pub struct PgLTree {
    labels: Vec<String>,
}

impl PgLTree {
    /// creates default/empty ltree
    pub fn new() -> Self {
        Self::default()
    }
Repository: launchbadge/sqlx
File: sqlx-core/src/postgres/types/ltree.rs (Rust)

Code before:

    /// LTree version not supported
    #[error("ltree version not supported")]
    InvalidLtreeVersion,
}

/// Represents an postgres ltree. Not that this is an EXTENSION!
#[derive(Clone, Debug, Default, PartialEq)]
pub struct PgLTree {
    labels: Vec<String>,
}

impl PgLTree {
    /// creates default/empty ltree
    pub fn new() -> Self {
        Self::default()
    }

    /// creates ltree from a [Vec<String>] without checking labels
    pub fn new_unchecked(labels: Vec<String>) -> Self {
        Self { labels }
    }

    /// creates ltree from an iterator with checking labels
    pub fn from_iter(
        labels: impl IntoIterator<Item = String, IntoIter = std::vec::IntoIter<String>>,
    ) -> Result<Self, Error> {
        let mut ltree = Self::default();
        for label in labels {
            ltree.push(label)?;
        }
        Ok(ltree)
    }

    /// push a label to ltree
    pub fn push(&mut self, label: String) -> Result<(), Error> {
        if label
            .bytes()
            .all(|c| c.is_ascii_alphabetic() || c.is_ascii_digit() || c == b'_')
        {
            self.labels.push(label);
            Ok(())
        } else {
            Err(Error::InvalidLtreeLabel)
        }
    }

    /// pop a label from ltree
    pub fn pop(&mut self) -> Option<String> {
        self.labels.pop()
    }

Review comment (suggestion):
Specifying `IntoIter` makes it work only with one type of `Iterator`

Code after:
    /// LTree labels can only contain [A-Za-z0-9_]
    #[error("ltree label cotains invalid characters")]
    InvalidLtreeLabel,

    /// LTree version not supported
    #[error("ltree version not supported")]
    InvalidLtreeVersion,
}

/// Container for a Label Tree (`ltree`) in Postgres.
///
/// See https://www.postgresql.org/docs/current/ltree.html
///
/// ### Note: Requires Postgres 13+
///
/// This integration requires that the `ltree` type support the binary format in the Postgres
/// wire protocol, which only became available in Postgres 13.
/// ([Postgres 13.0 Release Notes, Additional Modules][https://www.postgresql.org/docs/13/release-13.html#id-1.11.6.11.5.14])
///
/// Ideally, SQLx's Postgres driver should support falling back to text format for types
/// which don't have `typsend` and `typrecv` entries in `pg_type`, but that work still needs
/// to be done.
///
/// ### Note: Extension Required
/// The `ltree` extension is not enabled by default in Postgres. You will need to do so explicitly:
///
/// ```ignore
/// CREATE EXTENSION IF NOT EXISTS "ltree";
/// ```
#[derive(Clone, Debug, Default, PartialEq)]
pub struct PgLTree {
    labels: Vec<String>,
}

impl PgLTree {
    /// creates default/empty ltree
    pub fn new() -> Self {
        Self::default()
    }

    /// creates ltree from a [Vec<String>] without checking labels
    pub fn new_unchecked(labels: Vec<String>) -> Self {
        Self { labels }
    }

    /// creates ltree from an iterator with checking labels
    pub fn from_iter<I, S>(labels: I) -> Result<Self, PgLTreeParseError>
    where
        S: Into<String>,
        I: IntoIterator<Item = S>,
    {