Skip to content

Commit

Permalink
scylla-macros: introduce SerializeCql derive macro
Browse files Browse the repository at this point in the history
Introduce a derive macro which serializes a struct into a UDT.

Unlike the previous IntoUserType, the new macro takes care to match
the struct fields to UDT fields by their names. It does not assume that
the order of the fields in the Rust struct is the same as in the UDT.
  • Loading branch information
piodul committed Dec 9, 2023
1 parent 5733a2f commit 80a59a9
Show file tree
Hide file tree
Showing 10 changed files with 630 additions and 2 deletions.
48 changes: 48 additions & 0 deletions Cargo.lock.msrv

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions scylla-cql/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,16 @@ pub mod _macro_internal {
SerializedResult, SerializedValues, Value, ValueList, ValueTooBig,
};
pub use crate::macros::*;

pub use crate::types::serialize::value::{
BuiltinSerializationError as BuiltinTypeSerializationError,
BuiltinSerializationErrorKind as BuiltinTypeSerializationErrorKind,
BuiltinTypeCheckError as BuiltinTypeTypeCheckError,
BuiltinTypeCheckErrorKind as BuiltinTypeTypeCheckErrorKind, SerializeCql,
UdtSerializationErrorKind, UdtTypeCheckErrorKind,
};
pub use crate::types::serialize::writers::WrittenCellProof;
pub use crate::types::serialize::{CellValueBuilder, CellWriter, SerializationError};

pub use crate::frame::response::result::ColumnType;
}
62 changes: 62 additions & 0 deletions scylla-cql/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,68 @@ pub use scylla_macros::IntoUserType;
/// #[derive(ValueList)] allows to pass struct as a list of values for a query
pub use scylla_macros::ValueList;

/// Derive macro for the [`SerializeCql`](crate::types::serialize::value::SerializeCql) trait
/// which serializes given Rust structure as a User Defined Type (UDT).
///
/// At the moment, only structs with named fields are supported. The generated
/// implementation of the trait will match the struct fields to UDT fields
/// by name automatically.
///
/// Serialization will fail if there are some fields in the UDT that don't match
/// to any of the Rust struct fields, _or vice versa_.
///
/// In case of failure, either [`BuiltinTypeCheckError`](crate::types::serialize::value::BuiltinTypeCheckError)
/// or [`BuiltinSerializationError`](crate::types::serialize::value::BuiltinSerializationError)
/// will be returned.
///
/// # Example
///
/// A UDT defined like this:
///
/// ```notrust
/// CREATE TYPE ks.my_udt (a int, b text, c blob);
/// ```
///
/// ...can be serialized using the following struct:
///
/// ```rust
/// # use scylla_cql::macros::SerializeCql;
/// #[derive(SerializeCql)]
/// # #[scylla(crate = scylla_cql)]
/// struct MyUdt {
/// a: i32,
/// b: Option<String>,
/// c: Vec<u8>,
/// }
/// ```
///
/// # Attributes
///
/// `#[scylla(crate = crate_name)]`
///
/// By default, the code generated by the derive macro will refer to the items
/// defined by the driver (types, traits, etc.) via the `::scylla` path.
/// For example, it will refer to the [`SerializeCql`](crate::types::serialize::value::SerializeCql) trait
/// using the following path:
///
/// ```rust,ignore
/// use ::scylla::_macro_internal::SerializeCql;
/// ```
///
/// Most users will simply add `scylla` to their dependencies, then use
/// the derive macro and the path above will work. However, there are some
/// niche cases where this path will _not_ work:
///
/// - The `scylla` crate is imported under a different name,
/// - The `scylla` crate is _not imported at all_ - the macro actually
/// is defined in the `scylla-macros` crate and the generated code depends
/// on items defined in `scylla-cql`.
///
/// It's not possible to automatically resolve those issues in the procedural
/// macro itself, so in those cases the user must provide an alternative path
/// to either the `scylla` or `scylla-cql` crate.
pub use scylla_macros::SerializeCql;

// Reexports for derive(IntoUserType)
pub use bytes::{BufMut, Bytes, BytesMut};

Expand Down
Loading

0 comments on commit 80a59a9

Please sign in to comment.