Skip to content

Commit

Permalink
cxx-qt-lib: add support for bytes crate with QByteArray
Browse files Browse the repository at this point in the history
Related to #292
  • Loading branch information
ahayzen-kdab authored and Be-ing committed Feb 8, 2023
1 parent 9d0f36d commit d1c4b5e
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 2 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Support for further types: `QByteArray`, `QCoreApplication`, `QGuiApplication`, `QModelIndex`, `QPersistentModelIndex`, `QQmlApplicationEngine`, `QQmlEngine`, `QStringList`, `QVector2D`, `QVector3D`, `QVector4D`
- Support for nesting objects in properties, invokables, and signals with `*mut T`
- Allow for marking signals as existing in the base class
- Support for conversions to types in third-party crates: `http`, `rgb`, `url`
- Support for conversions to types in third-party crates: `bytes`, `http`, `rgb`, `url`

### Changed

Expand Down
2 changes: 2 additions & 0 deletions crates/cxx-qt-lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ links = "cxx-qt-lib"

[dependencies]
cxx.workspace = true
bytes = { version = "1.4", optional = true }
http = { version = "0.2", optional = true }
rgb = { version = "0.8", optional = true }
url = { version = "2.3", optional = true }
Expand All @@ -28,6 +29,7 @@ qt-build-utils.workspace = true

[features]
default = ["qt_gui", "qt_qml"]
bytes = ["dep:bytes"]
http = ["dep:http"]
rgb = ["dep:rgb"]
qt_gui = ["cxx-qt-lib-headers/qt_gui"]
Expand Down
47 changes: 46 additions & 1 deletion crates/cxx-qt-lib/src/core/qbytearray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,22 @@ impl From<&QByteArray> for Vec<u8> {
}
}

#[cfg(feature = "bytes")]
impl From<&bytes::Bytes> for QByteArray {
/// Convert `bytes::Bytes` to a QByteArray. This makes a deep copy of the data.
fn from(value: &bytes::Bytes) -> Self {
Self::from(value.as_ref())
}
}

#[cfg(feature = "bytes")]
impl From<&QByteArray> for bytes::Bytes {
/// Convert QByteArray to a `bytes::Bytes`. This makes a deep copy of the data.
fn from(value: &QByteArray) -> Self {
Self::copy_from_slice(value.as_ref())
}
}

impl QByteArray {
/// Inserts value at the end of the list.
pub fn append(&mut self, ch: u8) {
Expand All @@ -199,12 +215,24 @@ impl QByteArray {
ffi::qbytearray_fill(self, ch, size)
}

/// Construct a QByteArray from a `bytes::Bytes` without a deep copy
///
/// # Safety
///
/// The caller must ensure that the original `bytes::Bytes` outlives the QByteArray
/// and that the QByteArray is not modified
#[cfg(feature = "bytes")]
pub unsafe fn from_raw_bytes(bytes: &bytes::Bytes) -> Self {
Self::from_raw_data(bytes.as_ref())
}

/// Construct a QByteArray from a `&[u8]` without a deep copy
///
/// # Safety
///
/// The caller must ensure that the original slice outlives the QByteArray
pub unsafe fn from_raw_data(bytes: &[u8]) -> QByteArray {
/// and that the QByteArray is not modified
pub unsafe fn from_raw_data(bytes: &[u8]) -> Self {
ffi::qbytearray_from_raw_data(bytes)
}

Expand Down Expand Up @@ -251,3 +279,20 @@ unsafe impl ExternType for QByteArray {
type Id = type_id!("QByteArray");
type Kind = cxx::kind::Trivial;
}

#[cfg(test)]
mod tests {
#[cfg(feature = "bytes")]
use super::*;

#[cfg(feature = "bytes")]
#[test]
fn test_bytes() {
let bytes = bytes::Bytes::from("KDAB");
let qbytearray = QByteArray::from(&bytes);
assert_eq!(bytes.as_ref(), qbytearray.as_ref());

let bytes_bytes = bytes::Bytes::from(&qbytearray);
assert_eq!(bytes, bytes_bytes)
}
}

0 comments on commit d1c4b5e

Please sign in to comment.