blob: 021125d7e67f6fb9972efc8f4b0d0b4127f12169 [file]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
use bytes::Bytes;
use iggy::prelude::{IggyMessage as RustIggyMessage, IggyMessageHeader};
use pyo3::{prelude::*, types::PyBytes};
use pyo3_stub_gen::{
derive::{gen_stub_pyclass, gen_stub_pymethods},
impl_stub_type,
};
use std::str::FromStr;
/// A Python class representing a message to be sent.
/// This class wraps a Rust message meant for sending, facilitating
/// the creation of such messages from Python and their subsequent use in Rust.
#[pyclass(from_py_object)]
#[gen_stub_pyclass]
pub struct SendMessage {
pub(crate) inner: RustIggyMessage,
}
impl Clone for SendMessage {
fn clone(&self) -> Self {
Self {
inner: RustIggyMessage {
header: IggyMessageHeader {
checksum: self.inner.header.checksum,
id: self.inner.header.id,
offset: self.inner.header.offset,
timestamp: self.inner.header.timestamp,
origin_timestamp: self.inner.header.origin_timestamp,
user_headers_length: self.inner.header.user_headers_length,
payload_length: self.inner.header.payload_length,
reserved: self.inner.header.reserved,
},
payload: self.inner.payload.clone(),
user_headers: self.inner.user_headers.clone(),
},
}
}
}
#[gen_stub_pymethods]
#[pymethods]
impl SendMessage {
/// Constructs a new `SendMessage` instance from a string or bytes.
/// This method allows for the creation of a `SendMessage` instance
/// directly from Python using the provided string or bytes data.
#[new]
pub fn new(py: Python, data: PyMessagePayload) -> PyResult<Self> {
let inner = match data {
PyMessagePayload::String(data) => RustIggyMessage::from_str(&data)
.map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(e.to_string()))?,
PyMessagePayload::Bytes(data) => {
let bytes = Bytes::from(data.extract::<Vec<u8>>(py)?);
RustIggyMessage::builder()
.payload(bytes)
.build()
.map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(e.to_string()))?
}
};
Ok(Self { inner })
}
}
#[derive(FromPyObject, IntoPyObject)]
pub enum PyMessagePayload {
#[pyo3(transparent, annotation = "str")]
String(String),
#[pyo3(transparent, annotation = "bytes")]
Bytes(Py<PyBytes>),
}
impl_stub_type!(PyMessagePayload = String | PyBytes);