drone-micropython-core 0.1.1

MicroPython for Drone.
use core::slice;
use drone_core::ffi::{c_char, c_int, c_uint, c_void};
use drone_core::io::SeekFrom;
use drone_micropython_raw::{
  mp_import_stat_t, off_t, EINVAL, SEEK_CUR, SEEK_END, SEEK_SET,
};
use io::{Fd, Flags, IoReq, IoReqRes};
use rt::MP_ERRNO;

/// MicroPython I/O layer runtime.
pub trait IoRt {
  /// Makes I/O request.
  fn req(req: IoReq) -> IoReqRes;

  #[doc(hidden)]
  #[inline(always)]
  unsafe fn open(path: *const c_char, flags: c_char) -> c_int {
    let flags = Flags::new(flags);
    match Self::req(IoReq::Open { path, flags }).open {
      Ok(fd) => fd.to_c_int(),
      Err(err) => {
        MP_ERRNO = err;
        -1
      }
    }
  }

  #[doc(hidden)]
  #[inline(always)]
  unsafe fn read(fd: c_int, buf: *mut c_void, count: usize) -> isize {
    let fd = Fd::new(fd);
    let buf = slice::from_raw_parts_mut(buf as *mut u8, count);
    match Self::req(IoReq::Read { fd, buf }).read {
      Ok(n) => n as isize,
      Err(err) => {
        MP_ERRNO = err;
        -1
      }
    }
  }

  #[doc(hidden)]
  #[inline(always)]
  unsafe fn write(fd: c_int, buf: *const c_void, count: usize) -> isize {
    let fd = Fd::new(fd);
    let buf = slice::from_raw_parts(buf as *const u8, count);
    match Self::req(IoReq::Write { fd, buf }).write {
      Ok(n) => n as isize,
      Err(err) => {
        MP_ERRNO = err;
        -1
      }
    }
  }

  #[doc(hidden)]
  #[inline(always)]
  unsafe fn lseek(fd: c_int, offset: off_t, whence: c_int) -> off_t {
    let fd = Fd::new(fd);
    let pos = match whence as c_uint {
      SEEK_SET => SeekFrom::Start(offset as u64),
      SEEK_CUR => SeekFrom::Current(i64::from(offset)),
      SEEK_END => SeekFrom::End(i64::from(offset)),
      _ => {
        MP_ERRNO = EINVAL as c_int;
        return -1;
      }
    };
    match Self::req(IoReq::Seek { fd, pos }).seek {
      Ok(off) => off as off_t,
      Err(err) => {
        MP_ERRNO = err;
        -1
      }
    }
  }

  #[doc(hidden)]
  #[inline(always)]
  unsafe fn fsync(fd: c_int) -> c_int {
    let fd = Fd::new(fd);
    match Self::req(IoReq::Fsync { fd }).fsync {
      Ok(()) => 0,
      Err(err) => {
        MP_ERRNO = err;
        -1
      }
    }
  }

  #[doc(hidden)]
  #[inline(always)]
  unsafe fn close(fd: c_int) -> c_int {
    let fd = Fd::new(fd);
    match Self::req(IoReq::Close { fd }).close {
      Ok(()) => 0,
      Err(err) => {
        MP_ERRNO = err;
        -1
      }
    }
  }

  #[doc(hidden)]
  #[inline(always)]
  unsafe fn mp_import_stat(path: *const c_char) -> mp_import_stat_t {
    match Self::req(IoReq::ImportStat { path }).import_stat {
      Ok(import_stat) => import_stat,
      Err(_) => mp_import_stat_t::MP_IMPORT_STAT_NO_EXIST,
    }
  }
}