panda/plugins/guest_plugin_manager/
from_channel_msg.rs

1use std::str;
2
3/// Represents a type which can be converted to from a channel message sent by a
4/// guest plugin. Used by the [`channel_recv`](super::channel_recv) macro.
5///
6/// ## Supported Types
7/// * `&[u8]` - gives you the raw bytes
8/// * `Vec<u8>` - gives you the raw bytes, but owned
9/// * `&str` - gives you the bytes as a UTF-8 string. Prints a warning if invalid
10/// unicode and skips your callback.
11/// * `String` - same as `&str` but owned
12/// * `Option<T>` - rather than print a warning if the type can't be decoded, pass None
13/// * `Result<T, String>` - rather than print out the warning to stdout, pass the warning
14/// as a `String`
15pub trait FromChannelMessage: Sized {
16    unsafe fn from_channel_message(data: *const u8, size: usize) -> Result<Self, String>;
17}
18
19impl<'a> FromChannelMessage for &'a [u8] {
20    unsafe fn from_channel_message(data: *const u8, size: usize) -> Result<Self, String> {
21        Ok(std::slice::from_raw_parts(data, size))
22    }
23}
24
25impl FromChannelMessage for Vec<u8> {
26    unsafe fn from_channel_message(data: *const u8, size: usize) -> Result<Self, String> {
27        <&[u8]>::from_channel_message(data, size).map(ToOwned::to_owned)
28    }
29}
30
31impl<'a> FromChannelMessage for &'a str {
32    unsafe fn from_channel_message(data: *const u8, size: usize) -> Result<Self, String> {
33        <&[u8]>::from_channel_message(data, size)
34            .map(str::from_utf8)?
35            .map_err(|_| String::from("Channel message is not valid UTF-8"))
36    }
37}
38
39impl FromChannelMessage for String {
40    unsafe fn from_channel_message(data: *const u8, size: usize) -> Result<Self, String> {
41        <&str>::from_channel_message(data, size).map(ToOwned::to_owned)
42    }
43}
44
45impl<T: FromChannelMessage> FromChannelMessage for Option<T> {
46    unsafe fn from_channel_message(data: *const u8, size: usize) -> Result<Self, String> {
47        Ok(T::from_channel_message(data, size).ok())
48    }
49}
50
51impl<T: FromChannelMessage> FromChannelMessage for Result<T, String> {
52    unsafe fn from_channel_message(data: *const u8, size: usize) -> Result<Self, String> {
53        Ok(T::from_channel_message(data, size))
54    }
55}