use crate::core::{
self, ClPlatformIdPtr, PlatformId as PlatformIdCore, PlatformInfo, PlatformInfoResult,
};
use crate::error::{Error as OclError, Result as OclResult};
use crate::ffi::cl_platform_id;
use std;
use std::ops::{Deref, DerefMut};
use std::str::SplitWhitespace;
#[derive(Debug, thiserror::Error)]
pub enum PlatformError {
#[error("No platforms found.")]
NoPlatforms,
}
#[derive(Debug, Clone)]
pub struct Extensions {
inner: String,
}
impl Extensions {
pub fn iter(&self) -> SplitWhitespace {
self.inner.split_whitespace()
}
pub fn as_str(&self) -> &str {
&self.inner
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Hash)]
pub struct Platform(PlatformIdCore);
impl Platform {
pub fn list() -> Vec<Platform> {
let list_core =
core::get_platform_ids().expect("Platform::list: Error retrieving platform list");
list_core.into_iter().map(Platform::new).collect()
}
pub fn first() -> OclResult<Platform> {
core::get_platform_ids()?
.first()
.map(|&p| Platform::new(p))
.ok_or(PlatformError::NoPlatforms.into())
}
pub fn new(id_core: PlatformIdCore) -> Platform {
Platform(id_core)
}
pub fn list_from_core(platforms: Vec<PlatformIdCore>) -> Vec<Platform> {
platforms.into_iter().map(Platform::new).collect()
}
pub fn info(&self, info_kind: PlatformInfo) -> OclResult<PlatformInfoResult> {
core::get_platform_info(&self.0, info_kind).map_err(OclError::from)
}
pub fn profile(&self) -> OclResult<String> {
core::get_platform_info(&self.0, PlatformInfo::Profile)
.map(|r| r.into())
.map_err(OclError::from)
}
pub fn version(&self) -> OclResult<String> {
core::get_platform_info(&self.0, PlatformInfo::Version)
.map(|r| r.into())
.map_err(OclError::from)
}
pub fn name(&self) -> OclResult<String> {
core::get_platform_info(&self.0, PlatformInfo::Name)
.map(|r| r.into())
.map_err(OclError::from)
}
pub fn vendor(&self) -> OclResult<String> {
core::get_platform_info(&self.0, PlatformInfo::Vendor)
.map(|r| r.into())
.map_err(OclError::from)
}
pub fn extensions(&self) -> OclResult<Extensions> {
let extensions = core::get_platform_info(&self.0, PlatformInfo::Extensions);
extensions
.map(|e| Extensions { inner: e.into() })
.map_err(OclError::from)
}
pub fn as_core(&self) -> &PlatformIdCore {
&self.0
}
fn fmt_info(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
f.debug_struct("Platform")
.field("Profile", &self.info(PlatformInfo::Profile))
.field("Version", &self.info(PlatformInfo::Version))
.field("Name", &self.info(PlatformInfo::Name))
.field("Vendor", &self.info(PlatformInfo::Vendor))
.field("Extensions", &self.info(PlatformInfo::Extensions))
.finish()
}
}
unsafe impl ClPlatformIdPtr for Platform {
fn as_ptr(&self) -> cl_platform_id {
self.0.as_ptr()
}
}
impl Default for Platform {
fn default() -> Platform {
let dflt_plat_core = core::default_platform().expect("Platform::default()");
Platform::new(dflt_plat_core)
}
}
impl From<PlatformIdCore> for Platform {
fn from(core: PlatformIdCore) -> Platform {
Platform(core)
}
}
impl From<Platform> for String {
fn from(p: Platform) -> String {
format!("{}", p)
}
}
impl From<Platform> for PlatformIdCore {
fn from(p: Platform) -> PlatformIdCore {
p.0
}
}
impl<'a> From<&'a Platform> for PlatformIdCore {
fn from(p: &Platform) -> PlatformIdCore {
p.0.clone()
}
}
impl std::fmt::Display for Platform {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
self.fmt_info(f)
}
}
impl Deref for Platform {
type Target = PlatformIdCore;
fn deref(&self) -> &PlatformIdCore {
&self.0
}
}
impl DerefMut for Platform {
fn deref_mut(&mut self) -> &mut PlatformIdCore {
&mut self.0
}
}