Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 10 additions & 31 deletions python/rnet/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -196,45 +196,30 @@ class Message:
Returns the close code and reason of the message if it is a close message.
"""

@staticmethod
def text_from_json(json: Dict[str, Any]) -> "Message":
r"""
Creates a new text message from the JSON representation.

# Arguments
* `json` - The JSON representation of the message.
"""
...

@staticmethod
def binary_from_json(json: Dict[str, Any]) -> "Message":
r"""
Creates a new binary message from the JSON representation.

# Arguments
* `json` - The JSON representation of the message.
"""
...
json: Any
r"""
Returns the JSON representation of the message if it is a text message with JSON content.
"""

@staticmethod
def from_text(text: str) -> "Message":
def from_binary(data: bytes | Any) -> "Message":
r"""
Creates a new text message.
Creates a new binary message.

# Arguments

* `text` - The text content of the message.
* `data` - The binary data or any JSON-serializable data of the message.
"""
...

@staticmethod
def from_binary(data: bytes) -> "Message":
def from_text(data: str | Any) -> "Message":
r"""
Creates a new binary message.
Creates a new text message.

# Arguments

* `data` - The binary data of the message.
* `data` - The text content or any JSON-serializable data of the message.
"""
...

Expand Down Expand Up @@ -272,12 +257,6 @@ class Message:
"""
...

def json(self) -> Any:
r"""
Returns the JSON representation of the message.
"""
...

def __str__(self) -> str: ...

class Streamer:
Expand Down
83 changes: 42 additions & 41 deletions src/client/resp/ws/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//!
//! The `Message` type is used for sending and receiving WebSocket messages in a unified way.

use std::fmt;
use std::fmt::{self, Debug};

use bytes::Bytes;
use pyo3::{
Expand All @@ -18,23 +18,27 @@ use wreq::ws::message::{self, CloseCode, CloseFrame, Utf8Bytes};

use crate::{buffer::PyBuffer, client::body::Json, error::Error};

/// An enum representing either a bytes message or a JSON message.
#[derive(FromPyObject)]
pub enum BytesLike {
Bytes(PyBackedBytes),
Json(Json),
}

/// An enum representing either a text message or a JSON message.
#[derive(FromPyObject)]
pub enum TextLike {
Text(PyBackedStr),
Json(Json),
}

/// A WebSocket message.
#[derive(Debug, Clone)]
#[pyclass(subclass, str, frozen, from_py_object)]
pub struct Message(pub message::Message);

#[pymethods]
impl Message {
/// Returns the JSON representation of the message.
pub fn json(&self, py: Python) -> PyResult<Json> {
py.detach(|| {
self.0
.json::<Json>()
.map_err(Error::Library)
.map_err(Into::into)
})
}

/// Returns the data of the message as bytes.
#[getter]
pub fn data(&self) -> Option<PyBuffer> {
Expand Down Expand Up @@ -88,6 +92,12 @@ impl Message {
}
}

/// Returns the JSON representation of the message.
#[getter]
pub fn json(&self, py: Python) -> Option<Json> {
py.detach(|| self.0.json::<Json>().ok())
}

/// Returns the close code and reason of the message if it is a close message.
#[getter]
pub fn close(&self) -> Option<(u16, Option<&str>)> {
Expand All @@ -103,46 +113,36 @@ impl Message {
impl Message {
/// Creates a new text message from the JSON representation.
#[staticmethod]
#[pyo3(signature = (json))]
pub fn text_from_json(py: Python, json: Json) -> PyResult<Self> {
py.detach(|| {
message::Message::text_from_json(&json)
.map(Message)
#[pyo3(signature = (like))]
pub fn from_text(py: Python, like: TextLike) -> PyResult<Self> {
py.detach(|| match like {
TextLike::Text(text) => {
// If the string is not valid UTF-8, this will panic.
let msg = message::Message::text(
Utf8Bytes::try_from(Bytes::from_owner(text)).expect("valid UTF-8"),
);
Ok(Self(msg))
}
Comment thread
0x676e67 marked this conversation as resolved.
TextLike::Json(json) => message::Message::text_from_json(&json)
.map(Self)
.map_err(Error::Library)
.map_err(Into::into)
.map_err(Into::into),
})
}

/// Creates a new binary message from the JSON representation.
#[staticmethod]
#[pyo3(signature = (json))]
pub fn binary_from_json(py: Python, json: Json) -> PyResult<Self> {
py.detach(|| {
message::Message::binary_from_json(&json)
#[pyo3(signature = (like))]
pub fn from_binary(py: Python, like: BytesLike) -> PyResult<Self> {
py.detach(|| match like {
BytesLike::Bytes(bytes) => Ok(Self(message::Message::binary(Bytes::from_owner(bytes)))),
BytesLike::Json(json) => message::Message::binary_from_json(&json)
.map(Message)
.map_err(Error::Library)
.map_err(Into::into)
.map_err(Into::into),
})
}

/// Creates a new text message.
#[staticmethod]
#[pyo3(signature = (text))]
pub fn from_text(text: PyBackedStr) -> Self {
// If the string is not valid UTF-8, this will panic.
let msg = message::Message::text(
Utf8Bytes::try_from(Bytes::from_owner(text)).expect("valid UTF-8"),
);
Self(msg)
}

/// Creates a new binary message.
#[staticmethod]
#[pyo3(signature = (data))]
pub fn from_binary(data: PyBackedBytes) -> Self {
Self(message::Message::binary(Bytes::from_owner(data)))
}

/// Creates a new ping message.
#[staticmethod]
#[pyo3(signature = (data))]
Expand Down Expand Up @@ -174,7 +174,8 @@ impl Message {
}

impl fmt::Display for Message {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self.0)
self.0.fmt(f)
}
}
Loading