use crate::{domain::RegisteredString, NvtxError, Str, TypeValueEncodable};
use alloc::borrow::ToOwned;
use alloc::ffi::CString;
use alloc::string::String;
use core::ffi::CStr;
use widestring::{WideCStr, WideCString};
#[derive(Debug, Clone)]
pub enum GenericMessage<T = ()> {
Ascii(CString),
Unicode(WideCString),
Registered(T),
}
impl<T> From<Str> for GenericMessage<T> {
fn from(value: Str) -> Self {
match value {
Str::Ascii(s) => Self::Ascii(s),
Str::Unicode(s) => Self::Unicode(s),
}
}
}
impl<T> GenericMessage<T> {
#[must_use]
pub fn from_string_lossy(value: String) -> Self {
Self::from(Str::from_string_lossy(value))
}
#[must_use]
pub fn from_str_lossy(value: &str) -> Self {
Self::from(Str::from_str_lossy(value))
}
}
impl<'a, T> From<RegisteredString<'a>> for GenericMessage<T>
where
T: From<RegisteredString<'a>>,
{
fn from(v: RegisteredString<'a>) -> Self {
Self::Registered(v.into())
}
}
impl<T> From<CString> for GenericMessage<T> {
fn from(value: CString) -> Self {
Self::Ascii(value)
}
}
impl<T> From<WideCString> for GenericMessage<T> {
fn from(value: WideCString) -> Self {
Self::Unicode(value)
}
}
impl<T> From<&CStr> for GenericMessage<T> {
fn from(value: &CStr) -> Self {
Self::Ascii(value.to_owned())
}
}
impl<T> From<&WideCStr> for GenericMessage<T> {
fn from(value: &WideCStr) -> Self {
Self::Unicode(value.to_owned())
}
}
trait Encodable {
fn encode(&self) -> (nvtx_sys::MessageType, nvtx_sys::MessageValue);
}
impl Encodable for () {
fn encode(&self) -> (nvtx_sys::MessageType, nvtx_sys::MessageValue) {
debug_assert!(false, "{}", NvtxError::RegisteredStringInGlobalContext);
(
nvtx_sys::MessageType::NVTX_MESSAGE_UNKNOWN,
nvtx_sys::MessageValue {
ascii: core::ptr::null(),
},
)
}
}
impl Encodable for RegisteredString<'_> {
fn encode(&self) -> (nvtx_sys::MessageType, nvtx_sys::MessageValue) {
(
nvtx_sys::MessageType::NVTX_MESSAGE_TYPE_REGISTERED,
nvtx_sys::MessageValue {
registered: self.handle().into(),
},
)
}
}
impl<T> TypeValueEncodable for GenericMessage<T>
where
T: Encodable,
{
type Type = nvtx_sys::MessageType;
type Value = nvtx_sys::MessageValue;
fn encode(&self) -> (Self::Type, Self::Value) {
match self {
GenericMessage::Ascii(s) => (
Self::Type::NVTX_MESSAGE_TYPE_ASCII,
Self::Value { ascii: s.as_ptr() },
),
GenericMessage::Unicode(s) => (
Self::Type::NVTX_MESSAGE_TYPE_UNICODE,
Self::Value {
unicode: s.as_ptr().cast(),
},
),
GenericMessage::Registered(r) => r.encode(),
}
}
fn default_encoding() -> (Self::Type, Self::Value) {
(
Self::Type::NVTX_MESSAGE_UNKNOWN,
Self::Value {
ascii: core::ptr::null(),
},
)
}
}