Skip to content

Instantly share code, notes, and snippets.

@opalenic
Created December 1, 2016 00:41
Show Gist options
  • Save opalenic/674d2e014ef599c4fd4110dfb57c9b83 to your computer and use it in GitHub Desktop.
Save opalenic/674d2e014ef599c4fd4110dfb57c9b83 to your computer and use it in GitHub Desktop.
Rust compiler error
#![no_std]
#![feature(lang_items)]
mod messages;
#[lang = "panic_fmt"]
extern "C" fn panic_fmt() -> ! {
loop {
}
}
#![allow(dead_code,
non_camel_case_types,
non_upper_case_globals,
non_snake_case)]
use core::mem;
use core::ops::{Deref, DerefMut};
#[repr(u8)]
pub enum CVoid {
__val1,
__val2
}
#[derive(Copy, Clone)]
#[repr(u32)]
pub enum message_type {
MSG_SET_PLAN = 0,
MSG_GET_PLAN = 1,
MSG_SPIN_PLAN_REPLY = 2,
MSG_SET_SPIN_STATE = 3,
MSG_GET_SPIN_STATE = 4,
MSG_SPIN_STATE_REPLY = 5,
MSG_NUM_MESSAGE_TYPES = 6,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct spin_plan_data {
pub channel_num: u8,
pub spin_plan_leg_count: u32,
pub plan_legs: [pwm_leg; 10 as usize],
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct pwm_leg {
pub duration_msecs: u32,
pub target_pct: f32,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct spin_channel {
pub channel_num: u8,
}
#[derive(Copy, Clone)]
#[repr(u32)]
pub enum spin_state {
SPIN_STOPPED = 0,
SPIN_RUNNING = 1,
SPIN_SPINNING_DOWN = 2,
SPIN_NUM_SPIN_STATES = 3,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct spin_state_set_data {
pub channel_num: u8,
pub state: spin_state,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct spin_state_data {
pub channel_num: u8,
pub state: spin_state,
pub plan_time_elapsed_msecs: u64,
pub output_val_pct: f32,
_bindgen_padding_0_: [u8; 4usize],
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct raw_message {
msg_type: message_type,
data: *mut CVoid,
}
extern "C" {
pub fn msg_create_message(msg_type: message_type) -> *mut raw_message;
pub fn msg_free_message(msg: *mut raw_message);
}
pub enum Message<'a> {
SetSpinPlan(&'a mut spin_plan_data),
GetSpinPlan(&'a mut spin_channel),
SpinPlanReply(&'a mut spin_plan_data),
SetSpinState(&'a mut spin_state_set_data),
GetSpinState(&'a mut spin_channel),
SpinStateReply(&'a mut spin_state_data),
}
pub struct MessageWrapper<'a> {
msg_ptr: *mut raw_message,
pub payload: Message<'a>,
}
impl<'a> Into<*mut raw_message> for MessageWrapper<'a> {
fn into(self) -> *mut raw_message {
let msg_ptr = self.msg_ptr;
// mem::forget(self);
msg_ptr
}
}
impl<'a> MessageWrapper<'a> {
pub fn from_raw(msg_ptr: *mut raw_message) -> Result<MessageWrapper<'a>, ()> {
unsafe {
let payload = match (*msg_ptr).msg_type {
message_type::MSG_SET_PLAN => {
Message::SetSpinPlan(&mut *((*msg_ptr).data as *mut spin_plan_data))
}
message_type::MSG_GET_PLAN => {
Message::GetSpinPlan(&mut *((*msg_ptr).data as *mut spin_channel))
}
message_type::MSG_SPIN_PLAN_REPLY => {
Message::SpinPlanReply(&mut *((*msg_ptr).data as *mut spin_plan_data))
}
message_type::MSG_SET_SPIN_STATE => {
Message::SetSpinState(&mut *((*msg_ptr).data as *mut spin_state_set_data))
}
message_type::MSG_GET_SPIN_STATE => {
Message::GetSpinState(&mut *((*msg_ptr).data as *mut spin_channel))
}
message_type::MSG_SPIN_STATE_REPLY => {
Message::SpinStateReply(&mut *((*msg_ptr).data as *mut spin_state_data))
}
_ => {
return Err(());
}
};
Ok(MessageWrapper {
msg_ptr: msg_ptr,
payload: payload
})
}
}
pub fn new(msg_type: message_type) -> Result<MessageWrapper<'a>, ()> {
unsafe { MessageWrapper::from_raw(msg_create_message(msg_type)) }
}
}
impl<'a> Deref for MessageWrapper<'a> {
type Target = Message<'a>;
fn deref(&self) -> &Self::Target {
&self.payload
}
}
impl<'a> DerefMut for MessageWrapper<'a> {
fn deref_mut(&mut self) -> &mut Message<'a> {
&mut self.payload
}
}
impl<'a> Drop for MessageWrapper<'a> {
fn drop(&mut self) {
unsafe { msg_free_message(self.msg_ptr) }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment