Skip to content
Permalink
Browse files

Removed strongly-typed builders.

  • Loading branch information...
DanielKeep committed Feb 13, 2016
1 parent 549b8db commit 06af24662f7e406dfab1faa17f6f39d9e21e51e6
Showing with 60 additions and 154 deletions.
  1. +0 −20 src/util.rs
  2. +22 −40 src/wnd.rs
  3. +38 −94 src/wnd_class.rs
@@ -29,23 +29,3 @@ pub trait TryDrop: Sized {

unsafe fn try_drop_inner(&mut self) -> Result<(), Self::Err>;
}

pub trait Maybe<T> {
fn into_option(self) -> Option<T>;
}

pub struct Set<T>(pub T);

impl<T> Maybe<T> for Set<T> {
fn into_option(self) -> Option<T> {
Some(self.0)
}
}

pub struct Unset;

impl<T> Maybe<T> for Unset {
fn into_option(self) -> Option<T> {
None
}
}
@@ -2,10 +2,9 @@ use std::io;
use std::ptr;
use user32;
use winapi::*;
use wio::wide::ToWide;
use ::last_error;
use ::traits::{AsId, IdThunk, AsRaw};
use ::util::TryDrop;
use ::util::{TryDrop, WCString};
use super::wnd_class::WndClassId;

custom_derive! {
@@ -68,7 +67,7 @@ bitflags! {
pub struct Wnd(HWND);

impl Wnd {
pub fn new() -> WndBuilder<(), (), ()> {
pub fn new<'a>() -> WndBuilder<'a> {
WndBuilder::new()
}

@@ -139,67 +138,50 @@ impl TryDrop for Wnd {
}
}

pub struct WndBuilder<
ClassName,
WindowName,
Style,
> {
class_name: ClassName,
window_name: WindowName,
style: Style,
pub struct WndBuilder<'a> {
class_name: Option<Box<IdThunk<WndClassId> + 'a>>,
window_name: Option<WCString>,
style: Option<WndStyle>,
}

impl WndBuilder<(), (), ()> {
impl<'a> WndBuilder<'a> {
fn new() -> Self {
WndBuilder {
class_name: (),
window_name: (),
style: (),
class_name: None,
window_name: None,
style: None,
}
}
}

impl<T0, T1> WndBuilder<(), T0, T1> {
pub fn class_name<T>(self, value: T) -> WndBuilder<T, T0, T1>
where T: AsId<WndClassId> {
pub fn class_name<T: 'a + AsId<WndClassId>>(self, value: T) -> Self {
WndBuilder {
class_name: value,
window_name: self.window_name,
style: self.style,
class_name: Some(Box::new(value.into_id_thunk())),
..self
}
}
}

impl<T0, T1> WndBuilder<T0, (), T1> {
pub fn window_name(self, value: &str) -> WndBuilder<T0, &str, T1> {
pub fn window_name(self, value: &str) -> Self {
WndBuilder {
class_name: self.class_name,
window_name: value,
style: self.style,
window_name: Some(value.into()),
..self
}
}
}

impl<T0, T1> WndBuilder<T0, T1, ()> {
pub fn style(self, value: WndStyle) -> WndBuilder<T0, T1, WndStyle> {
pub fn style(self, value: WndStyle) -> Self {
WndBuilder {
class_name: self.class_name,
window_name: self.window_name,
style: value,
style: Some(value),
..self
}
}
}

impl<'a, ClassName> WndBuilder<ClassName, &'a str, WndStyle>
where ClassName: AsId<WndClassId> {
pub fn create(self) -> io::Result<Wnd> {
unsafe {
let ex_style = 0;
let class_name = self.class_name.into_id_thunk();
let class_name = self.class_name.expect("missing class_name");
let (class_name, instance) = class_name.as_id().unpack();
let window_name = self.window_name.to_wide_null();
let window_name = self.window_name.expect("missing window_name");
let window_name = window_name.as_ptr();
let style = self.style.bits;
let style = self.style.expect("missing style").bits;
let x = CW_USEDEFAULT;
let y = CW_USEDEFAULT;
let width = CW_USEDEFAULT;
@@ -4,13 +4,9 @@ use std::ptr;
use conv::prelude::*;
use user32;
use winapi::*;
use wio::wide::ToWide;
use ::last_error;
use ::traits::{AsId, IdThunk, IntoRaw};
use ::util::{
WCString, TryDrop,
Maybe, Unset, Set,
};
use ::util::{WCString, TryDrop};

pub type WndProcRef = unsafe extern "system" fn(wnd: HWND, message: UINT, w_param: WPARAM, l_param: LPARAM) -> LRESULT;

@@ -89,126 +85,74 @@ impl IdThunk<WndClassId> for WCString {
}
}

pub struct WndClassBuilder<
WndProc = Unset,
ClsExtra = Unset,
WndExtra = Unset,
Instance = Unset,
Cursor = Unset,
ClassName = Unset,
Background = Unset,
> {
wnd_proc: WndProc,
cls_extra: ClsExtra,
wnd_extra: WndExtra,
instance: Instance,
cursor: Cursor,
background: Background,
class_name: ClassName,
pub struct WndClassBuilder {
wnd_proc: Option<WndProcRef>,
cls_extra: Option<usize>,
wnd_extra: Option<usize>,
instance: Option<HINSTANCE>,
cursor: Option<HCURSOR>,
background: Option<HBRUSH>,
class_name: Option<WCString>,
}

impl WndClassBuilder {
fn new() -> Self {
WndClassBuilder {
wnd_proc: Unset,
cls_extra: Unset,
wnd_extra: Unset,
instance: Unset,
cursor: Unset,
background: Unset,
class_name: Unset,
wnd_proc: None,
cls_extra: None,
wnd_extra: None,
instance: None,
cursor: None,
background: None,
class_name: None,
}
}
}

impl<T0, T1, T2, T3, T4, T5> WndClassBuilder<Unset, T3, T4, T0, T1, T2, T5> {
pub fn wnd_proc(self, wnd_proc: WndProcRef) -> WndClassBuilder<WndProcRef, T3, T4, T0, T1, T2, T5> {
pub fn wnd_proc(self, wnd_proc: WndProcRef) -> WndClassBuilder {
WndClassBuilder {
wnd_proc: wnd_proc,
cls_extra: self.cls_extra,
wnd_extra: self.wnd_extra,
instance: self.instance,
cursor: self.cursor,
class_name: self.class_name,
background: self.background,
wnd_proc: Some(wnd_proc),
..self
}
}
}

impl<T0, T1, T2, T3, T4, T5> WndClassBuilder<T0, T3, T4, Unset, T1, T2, T5> {
pub fn instance(self, instance: HINSTANCE) -> WndClassBuilder<T0, T3, T4, HINSTANCE, T1, T2, T5> {
pub fn instance(self, instance: HINSTANCE) -> WndClassBuilder {
WndClassBuilder {
wnd_proc: self.wnd_proc,
cls_extra: self.cls_extra,
wnd_extra: self.wnd_extra,
instance: instance,
cursor: self.cursor,
class_name: self.class_name,
background: self.background,
instance: Some(instance),
..self
}
}
}

impl<T0, T1, T2, T3, T4, T5> WndClassBuilder<T0, T3, T4, T1, Unset, T2, T5> {
pub fn cursor<Cursor: IntoRaw<Raw=HCURSOR>>(self, cursor: Cursor) -> WndClassBuilder<T0, T3, T4, T1, Set<HCURSOR>, T2, T5> {
pub fn cursor<Cursor: IntoRaw<Raw=HCURSOR>>(self, cursor: Cursor) -> WndClassBuilder {
WndClassBuilder {
wnd_proc: self.wnd_proc,
cls_extra: self.cls_extra,
wnd_extra: self.wnd_extra,
instance: self.instance,
cursor: Set(cursor.into_raw()),
class_name: self.class_name,
background: self.background,
cursor: Some(cursor.into_raw()),
..self
}
}
}

impl<T0, T1, T2, T3, T4, T5> WndClassBuilder<T0, T3, T4, T1, T2, Unset, T5> {
pub fn class_name(self, class_name: &str) -> WndClassBuilder<T0, T3, T4, T1, T2, &str, T5> {
pub fn class_name(self, class_name: &str) -> WndClassBuilder {
WndClassBuilder {
wnd_proc: self.wnd_proc,
cls_extra: self.cls_extra,
wnd_extra: self.wnd_extra,
instance: self.instance,
cursor: self.cursor,
class_name: class_name,
background: self.background,
class_name: Some(class_name.into()),
..self
}
}
}

impl<T0, T1, T2, T3, T4, T5> WndClassBuilder<T0, T3, T4, T1, T2, T5, Unset> {
pub fn background<Background: IntoRaw<Raw=HBRUSH>>(self, background: Background) -> WndClassBuilder<T0, T3, T4, T1, T2, T5, Set<HBRUSH>> {
pub fn background<Background: IntoRaw<Raw=HBRUSH>>(self, background: Background) -> WndClassBuilder {
WndClassBuilder {
wnd_proc: self.wnd_proc,
cls_extra: self.cls_extra,
wnd_extra: self.wnd_extra,
instance: self.instance,
cursor: self.cursor,
class_name: self.class_name,
background: Set(background.into_raw()),
background: Some(background.into_raw()),
..self
}
}
}

impl<'a, ClsExtra, WndExtra, Cursor, Background>
WndClassBuilder<WndProcRef, ClsExtra, WndExtra, HINSTANCE, Cursor, &'a str, Background>
where
ClsExtra: Maybe<usize>,
WndExtra: Maybe<usize>,
Cursor: Maybe<HCURSOR>,
Background: Maybe<HBRUSH>,
{
pub fn register(self) -> io::Result<WndClass> {
unsafe {
let wnd_proc = self.wnd_proc;
let cls_extra = try!(usize_2_int(self.cls_extra.into_option().unwrap_or(0)));
let wnd_extra = try!(usize_2_int(self.wnd_extra.into_option().unwrap_or(0)));
let instance = self.instance;
let cursor = self.cursor.into_option().unwrap_or(ptr::null_mut());
let class_name = self.class_name.to_wide_null();
let wnd_proc = self.wnd_proc.expect("missing wnd_class");
let cls_extra = try!(usize_2_int(self.cls_extra.unwrap_or(0)));
let wnd_extra = try!(usize_2_int(self.wnd_extra.unwrap_or(0)));
let instance = self.instance.expect("missing instance");
let cursor = self.cursor.unwrap_or(ptr::null_mut());
let class_name = self.class_name.expect("missing class_name");
let class_name = class_name.as_ptr();
let background = self.background.into_option().unwrap_or(ptr::null_mut());
let background = self.background.unwrap_or(ptr::null_mut());

let wnd_class = WNDCLASSEXW {
cbSize: mem::size_of::<WNDCLASSEXW>().value_into().unwrap_ok(),

0 comments on commit 06af246

Please sign in to comment.
You can’t perform that action at this time.