<commit_before>use std::io;
use std::io::Write;
use std::str::from_utf8;

use dbutil::normalize_position;
use error::OperationError;
use rdbutil::constants::*;
use rdbutil::{EncodeError, encode_i64, encode_slice_u8};

#[derive(PartialEq, Debug, Clone)]
pub enum ValueString {
    Integer(i64),
    Data(Vec<u8>),
}

impl ValueString {
    pub fn new(newvalue: Vec<u8>) -> Self {
        if newvalue.len() < 32 { // ought to be enough!
            if let Ok(utf8) = from_utf8(&*newvalue) {
                if let Ok(i) = utf8.parse::<i64>() {
                    return ValueString::Integer(i);
                }
            }
        }
        return ValueString::Data(newvalue);
    }

    pub fn to_vec(&self) -> Vec<u8> {
        match *self {
            ValueString::Data(ref data) => data.clone(),
            ValueString::Integer(ref int) => format!("{}", int).into_bytes(),
        }
    }

    pub fn strlen(&self) -> usize {
        match *self {
            ValueString::Data(ref data) => data.len(),
            ValueString::Integer(ref int) => format!("{}", int).len(),
        }
    }

    pub fn append(&mut self, newvalue: Vec<u8>) {
        match *self {
            ValueString::Data(ref mut data) => data.extend(newvalue),
            ValueString::Integer(i) => {
                let oldstr = format!("{}", i);
                *self = ValueString::new([oldstr.into_bytes(), newvalue].concat());
            },
        };
    }

    pub fn incr(&mut self, incr: i64) -> Result<i64, OperationError> {
        let val = match *self {
            ValueString::Integer(i) => i,
            ValueString::Data(ref data) => {
                if data.len() > 32 {
                    return Err(OperationError::OverflowError);
                }
                let res = try!(from_utf8(&data));
                try!(res.parse::<i64>())
            },
        };
        let newval = try!(val.checked_add(incr).ok_or(OperationError::OverflowError));
        *self = ValueString::Integer(newval.clone());
        Ok(newval)
    }

    pub fn incrbyfloat(&mut self, incr: f64) -> Result<f64, OperationError> {
        let val = match *self {
            ValueString::Integer(i) => i as f64,
            ValueString::Data(ref data) => {
                if data.len() > 32 {
                    return Err(OperationError::OverflowError);
                }
                let res = try!(from_utf8(&data));
                try!(res.parse::<f64>())
            },
        };
        let newval = val + incr;
        *self = ValueString::Data(format!("{}", newval).into_bytes());
        Ok(newval)
    }

    pub fn getrange(&self, _start: i64, _stop: i64) -> Vec<u8> {
        let s = match *self {
            ValueString::Integer(ref i) => format!("{}", i).into_bytes(),
            ValueString::Data(ref s) => s.clone(),
        };

        let len = s.len();
        let start = match normalize_position(_start, len) {
            Ok(i) => i,
            Err(g) => if !g { 0 } else { return Vec::new(); }
        } as usize;
        let stop = match normalize_position(_stop, len) {
            Ok(i) => i,
            Err(g) => if !g { return Vec::new(); } else { len - 1 }
        } as usize;

        if stop < start {
            return Vec::new();
        }

        let mut v = Vec::with_capacity(stop - start + 1);
        v.extend(s[start..stop + 1].iter());
        v
    }

    pub fn setbit(&mut self, bitoffset: usize, on: bool) -> bool {
        match *self {
            ValueString::Integer(i) => *self = ValueString::Data(format!("{}", i).into_bytes()),
            ValueString::Data(_) => (),
        };
        let mut d = match *self {
            ValueString::Data(ref mut d) => d,
            _ => panic!("Value should be data"),
        };

        let byte = bitoffset >> 3;

        while byte + 1 > d.len() {
            d.push(0);
        }

        let mut byteval = d[byte];
        let bit = 7 - (bitoffset & 0x7);
        let bitval = byteval & (1 << bit);

        byteval &= !(1 << bit);
        byteval |= (if on { 1 } else { 0 } & 0x1) << bit;
        d[byte] = byteval;

        bitval != 0
    }

    pub fn getbit(&self, bitoffset: usize) -> bool {
        let tmp;
        let d = match *self {
            ValueString::Integer(i) => { tmp = format!("{}", i).into_bytes(); &tmp },
            ValueString::Data(ref d) => d,
        };

        let byte = bitoffset >> 3;
        if byte >= d.len() {
            return false;
        }

        let bit = 7 - (bitoffset & 0x7);;
        let bitval = d[byte] & (1 << bit);

        bitval != 0
    }

    pub fn setrange(&mut self, _index: usize, data: Vec<u8>) -> usize {
        if data.len() == 0 {
            return self.strlen();
        }

        match *self {
            ValueString::Integer(i) => *self = ValueString::Data(format!("{}", i).into_bytes()),
            ValueString::Data(_) => (),
        }

        let mut d = match self {
            &mut ValueString::Data(ref mut s) => s,
            _ => panic!("String must be data"),
        };

        let mut index = _index;
        for _ in d.len()..index {
            d.push(0);
        }
        for c in data {
            d.push(c);
            if index < d.len() - 1 {
                d.swap_remove(index);
            }
            index += 1;
        }
        d.len()
    }

    pub fn dump<T: Write>(&self, writer: &mut T) -> io::Result<usize> {
        let mut v = vec![];
        match *self {
            ValueString::Integer(ref i) => match encode_i64(i.clone(), &mut v) {
                Ok(s) => s,
                Err(e) => match e {
                    EncodeError::IOError(e) => return Err(e),
                    EncodeError::OverflowError => try!(encode_slice_u8(&*self.to_vec(), &mut v, false))
                }
            },
            ValueString::Data(ref d) => try!(encode_slice_u8(&*d, &mut v, true)),
        };
        let data = [
            vec![TYPE_STRING],
            v,
            vec![(VERSION & 0xff) as u8],
            vec![((VERSION >> 8) & 0xff) as u8],
        ].concat();
        writer.write(&*data)
    }

    pub fn debug_object(&self) -> String {
        let mut serialized_data = vec![];
        let serialized = self.dump(&mut serialized_data).unwrap();
        let encoding = match *self {
            ValueString::Integer(_) => "int",
            ValueString::Data(_) => "raw",
        };
        format!("Value at:0x0000000000 refcount:1 encoding:{} serializedlength:{} lru:0 lru_seconds_idle:0", encoding, serialized).to_owned()
    }
}

#[cfg(test)]
mod test_rdb {
    use std::i64;

    use super::ValueString;

    #[test]
    fn dump_integer() {
        let mut v = vec![];
        ValueString::Integer(1).dump(&mut v).unwrap();
        assert_eq!(&*v, b"\x00\xc0\x01\x07\x00");
    }

    #[test]
    fn dump_integer_overflow() {
        let mut v = vec![];
        ValueString::Integer(i64::MAX).dump(&mut v).unwrap();
        assert_eq!(&*v, b"\x00\x139223372036854775807\x07\x00");
    }

    #[test]
    fn dump_string() {
        let mut v = vec![];
        ValueString::Data(b"hello world".to_vec()).dump(&mut v).unwrap();
        assert_eq!(&*v, b"\x00\x0bhello world\x07\x00");
    }
}
<commit_msg>Fix missing 0 in string data<commit_after>use std::io;
use std::io::Write;
use std::str::from_utf8;

use dbutil::normalize_position;
use error::OperationError;
use rdbutil::constants::*;
use rdbutil::{EncodeError, encode_i64, encode_slice_u8};

#[derive(PartialEq, Debug, Clone)]
pub enum ValueString {
    Integer(i64),
    Data(Vec<u8>),
}

impl ValueString {
    pub fn new(newvalue: Vec<u8>) -> Self {
        if newvalue.len() > 0 && newvalue.len() < 32 { // ought to be enough!
            if newvalue[0] as char != '0' {
                if let Ok(utf8) = from_utf8(&*newvalue) {
                    if let Ok(i) = utf8.parse::<i64>() {
                        return ValueString::Integer(i);
                    }
                }
            }
        }
        return ValueString::Data(newvalue);
    }

    pub fn to_vec(&self) -> Vec<u8> {
        match *self {
            ValueString::Data(ref data) => data.clone(),
            ValueString::Integer(ref int) => format!("{}", int).into_bytes(),
        }
    }

    pub fn strlen(&self) -> usize {
        match *self {
            ValueString::Data(ref data) => data.len(),
            ValueString::Integer(ref int) => format!("{}", int).len(),
        }
    }

    pub fn append(&mut self, newvalue: Vec<u8>) {
        match *self {
            ValueString::Data(ref mut data) => data.extend(newvalue),
            ValueString::Integer(i) => {
                let oldstr = format!("{}", i);
                *self = ValueString::new([oldstr.into_bytes(), newvalue].concat());
            },
        };
    }

    pub fn incr(&mut self, incr: i64) -> Result<i64, OperationError> {
        let val = match *self {
            ValueString::Integer(i) => i,
            ValueString::Data(ref data) => {
                if data.len() > 32 {
                    return Err(OperationError::OverflowError);
                }
                let res = try!(from_utf8(&data));
                try!(res.parse::<i64>())
            },
        };
        let newval = try!(val.checked_add(incr).ok_or(OperationError::OverflowError));
        *self = ValueString::Integer(newval.clone());
        Ok(newval)
    }

    pub fn incrbyfloat(&mut self, incr: f64) -> Result<f64, OperationError> {
        let val = match *self {
            ValueString::Integer(i) => i as f64,
            ValueString::Data(ref data) => {
                if data.len() > 32 {
                    return Err(OperationError::OverflowError);
                }
                let res = try!(from_utf8(&data));
                try!(res.parse::<f64>())
            },
        };
        let newval = val + incr;
        *self = ValueString::Data(format!("{}", newval).into_bytes());
        Ok(newval)
    }

    pub fn getrange(&self, _start: i64, _stop: i64) -> Vec<u8> {
        let s = match *self {
            ValueString::Integer(ref i) => format!("{}", i).into_bytes(),
            ValueString::Data(ref s) => s.clone(),
        };

        let len = s.len();
        let start = match normalize_position(_start, len) {
            Ok(i) => i,
            Err(g) => if !g { 0 } else { return Vec::new(); }
        } as usize;
        let stop = match normalize_position(_stop, len) {
            Ok(i) => i,
            Err(g) => if !g { return Vec::new(); } else { len - 1 }
        } as usize;

        if stop < start {
            return Vec::new();
        }

        let mut v = Vec::with_capacity(stop - start + 1);
        v.extend(s[start..stop + 1].iter());
        v
    }

    pub fn setbit(&mut self, bitoffset: usize, on: bool) -> bool {
        match *self {
            ValueString::Integer(i) => *self = ValueString::Data(format!("{}", i).into_bytes()),
            ValueString::Data(_) => (),
        };
        let mut d = match *self {
            ValueString::Data(ref mut d) => d,
            _ => panic!("Value should be data"),
        };

        let byte = bitoffset >> 3;

        while byte + 1 > d.len() {
            d.push(0);
        }

        let mut byteval = d[byte];
        let bit = 7 - (bitoffset & 0x7);
        let bitval = byteval & (1 << bit);

        byteval &= !(1 << bit);
        byteval |= (if on { 1 } else { 0 } & 0x1) << bit;
        d[byte] = byteval;

        bitval != 0
    }

    pub fn getbit(&self, bitoffset: usize) -> bool {
        let tmp;
        let d = match *self {
            ValueString::Integer(i) => { tmp = format!("{}", i).into_bytes(); &tmp },
            ValueString::Data(ref d) => d,
        };

        let byte = bitoffset >> 3;
        if byte >= d.len() {
            return false;
        }

        let bit = 7 - (bitoffset & 0x7);;
        let bitval = d[byte] & (1 << bit);

        bitval != 0
    }

    pub fn setrange(&mut self, _index: usize, data: Vec<u8>) -> usize {
        if data.len() == 0 {
            return self.strlen();
        }

        match *self {
            ValueString::Integer(i) => *self = ValueString::Data(format!("{}", i).into_bytes()),
            ValueString::Data(_) => (),
        }

        let mut d = match self {
            &mut ValueString::Data(ref mut s) => s,
            _ => panic!("String must be data"),
        };

        let mut index = _index;
        for _ in d.len()..index {
            d.push(0);
        }
        for c in data {
            d.push(c);
            if index < d.len() - 1 {
                d.swap_remove(index);
            }
            index += 1;
        }
        d.len()
    }

    pub fn dump<T: Write>(&self, writer: &mut T) -> io::Result<usize> {
        let mut v = vec![];
        match *self {
            ValueString::Integer(ref i) => match encode_i64(i.clone(), &mut v) {
                Ok(s) => s,
                Err(e) => match e {
                    EncodeError::IOError(e) => return Err(e),
                    EncodeError::OverflowError => try!(encode_slice_u8(&*self.to_vec(), &mut v, false))
                }
            },
            ValueString::Data(ref d) => try!(encode_slice_u8(&*d, &mut v, true)),
        };
        let data = [
            vec![TYPE_STRING],
            v,
            vec![(VERSION & 0xff) as u8],
            vec![((VERSION >> 8) & 0xff) as u8],
        ].concat();
        writer.write(&*data)
    }

    pub fn debug_object(&self) -> String {
        let mut serialized_data = vec![];
        let serialized = self.dump(&mut serialized_data).unwrap();
        let encoding = match *self {
            ValueString::Integer(_) => "int",
            ValueString::Data(_) => "raw",
        };
        format!("Value at:0x0000000000 refcount:1 encoding:{} serializedlength:{} lru:0 lru_seconds_idle:0", encoding, serialized).to_owned()
    }
}

#[cfg(test)]
mod test_rdb {
    use std::i64;

    use super::ValueString;

    #[test]
    fn dump_integer() {
        let mut v = vec![];
        ValueString::Integer(1).dump(&mut v).unwrap();
        assert_eq!(&*v, b"\x00\xc0\x01\x07\x00");
    }

    #[test]
    fn dump_integer_overflow() {
        let mut v = vec![];
        ValueString::Integer(i64::MAX).dump(&mut v).unwrap();
        assert_eq!(&*v, b"\x00\x139223372036854775807\x07\x00");
    }

    #[test]
    fn dump_string() {
        let mut v = vec![];
        ValueString::Data(b"hello world".to_vec()).dump(&mut v).unwrap();
        assert_eq!(&*v, b"\x00\x0bhello world\x07\x00");
    }
}
<|endoftext|>


<commit_before>use crate::cell::UnsafeCell;
use crate::sys::c;
use crate::sys::mutex::{self, Mutex};
use crate::sys::os;
use crate::time::Duration;

pub struct Condvar {
    inner: UnsafeCell<c::CONDITION_VARIABLE>,
}

pub type MovableCondvar = Box<Condvar>;

unsafe impl Send for Condvar {}
unsafe impl Sync for Condvar {}

impl Condvar {
    pub const fn new() -> Condvar {
        Condvar { inner: UnsafeCell::new(c::CONDITION_VARIABLE_INIT) }
    }

    #[inline]
    pub unsafe fn init(&mut self) {}

    #[inline]
    pub unsafe fn wait(&self, mutex: &Mutex) {
        let r = c::SleepConditionVariableSRW(self.inner.get(), mutex::raw(mutex), c::INFINITE, 0);
        debug_assert!(r != 0);
    }

    pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
        let r = c::SleepConditionVariableSRW(
            self.inner.get(),
            mutex::raw(mutex),
            super::dur2timeout(dur),
            0,
        );
        if r == 0 {
            debug_assert_eq!(os::errno() as usize, c::ERROR_TIMEOUT as usize);
            false
        } else {
            true
        }
    }

    #[inline]
    pub unsafe fn notify_one(&self) {
        c::WakeConditionVariable(self.inner.get())
    }

    #[inline]
    pub unsafe fn notify_all(&self) {
        c::WakeAllConditionVariable(self.inner.get())
    }

    pub unsafe fn destroy(&self) {
        // ...
    }
}
<commit_msg>No longer put windows condvars in a box.<commit_after>use crate::cell::UnsafeCell;
use crate::sys::c;
use crate::sys::mutex::{self, Mutex};
use crate::sys::os;
use crate::time::Duration;

pub struct Condvar {
    inner: UnsafeCell<c::CONDITION_VARIABLE>,
}

pub type MovableCondvar = Condvar;

unsafe impl Send for Condvar {}
unsafe impl Sync for Condvar {}

impl Condvar {
    pub const fn new() -> Condvar {
        Condvar { inner: UnsafeCell::new(c::CONDITION_VARIABLE_INIT) }
    }

    #[inline]
    pub unsafe fn init(&mut self) {}

    #[inline]
    pub unsafe fn wait(&self, mutex: &Mutex) {
        let r = c::SleepConditionVariableSRW(self.inner.get(), mutex::raw(mutex), c::INFINITE, 0);
        debug_assert!(r != 0);
    }

    pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
        let r = c::SleepConditionVariableSRW(
            self.inner.get(),
            mutex::raw(mutex),
            super::dur2timeout(dur),
            0,
        );
        if r == 0 {
            debug_assert_eq!(os::errno() as usize, c::ERROR_TIMEOUT as usize);
            false
        } else {
            true
        }
    }

    #[inline]
    pub unsafe fn notify_one(&self) {
        c::WakeConditionVariable(self.inner.get())
    }

    #[inline]
    pub unsafe fn notify_all(&self) {
        c::WakeAllConditionVariable(self.inner.get())
    }

    pub unsafe fn destroy(&self) {
        // ...
    }
}
<|endoftext|>


<commit_before>extern crate clap;
extern crate libimagrt;
extern crate libimagentrytag;
extern crate libimagutil;
#[macro_use] extern crate version;

use clap::Shell;
use libimagrt::runtime::Runtime;

macro_rules! gen_types_buildui {
    ($(($p:expr, $n:ident)$(,)*)*) => (
        $(
            mod $n {
                include!($p);
            }
         )*
        )
}

gen_types_buildui!(
    ("../imag-bookmark/src/ui.rs",  imagbookmark),
    ("../imag-counter/src/ui.rs",   imagcounter),
    ("../imag-diary/src/ui.rs",     imagdiary),
    ("../imag-link/src/ui.rs",      imaglink),
    ("../imag-notes/src/ui.rs",     imagnotes),
    ("../imag-ref/src/ui.rs",       imagref),
    ("../imag-store/src/ui.rs",     imagstore),
    ("../imag-tag/src/ui.rs",       imagtag),
    ("../imag-todo/src/ui.rs",      imagtodo),
    ("../imag-view/src/ui.rs",      imagview)
    );

fn main() {
    let mut app = Runtime::get_default_cli_builder(
        "imag",
        &version!()[..],
        "imag")
        .subcommand(
            imagbookmark::build_ui(Runtime::get_default_cli_builder(
                    "bookmark",
                    &version!()[..],
                    "bookmark")))
        .subcommand(
            imagcounter::build_ui(Runtime::get_default_cli_builder(
                    "counter",
                    &version!()[..],
                    "counter")))
        .subcommand(
            imagdiary::build_ui(Runtime::get_default_cli_builder(
                    "diary",
                    &version!()[..],
                    "diary")))
        .subcommand(
            imaglink::build_ui(Runtime::get_default_cli_builder(
                    "link",
                    &version!()[..],
                    "link")))
        .subcommand(
            imagnotes::build_ui(Runtime::get_default_cli_builder(
                    "notes",
                    &version!()[..],
                    "notes")))
        .subcommand(
            imagref::build_ui(Runtime::get_default_cli_builder(
                    "ref",
                    &version!()[..],
                    "ref")))
        .subcommand(
            imagstore::build_ui(Runtime::get_default_cli_builder(
                    "store",
                    &version!()[..],
                    "store")))
        .subcommand(
            imagtag::build_ui(Runtime::get_default_cli_builder(
                    "tag",
                    &version!()[..],
                    "tag")))
        .subcommand(
            imagtodo::build_ui(Runtime::get_default_cli_builder(
                    "todo",
                    &version!()[..],
                    "todo")))
        .subcommand(
            imagview::build_ui(Runtime::get_default_cli_builder(
                    "view",
                    &version!()[..],
                    "view")))
        ;
    app.gen_completions("imag", Shell::Bash, env!("OUT_DIR"));
    app.gen_completions("imag", Shell::Fish, env!("OUT_DIR"));
    app.gen_completions("imag", Shell::Zsh, env!("OUT_DIR"));

}
<commit_msg>Add build_subcommand! macro<commit_after>extern crate clap;
extern crate libimagrt;
extern crate libimagentrytag;
extern crate libimagutil;
#[macro_use] extern crate version;

use clap::Shell;
use libimagrt::runtime::Runtime;

macro_rules! gen_types_buildui {
    ($(($p:expr, $n:ident)$(,)*)*) => (
        $(
            mod $n {
                include!($p);
            }
         )*
        )
}

macro_rules! build_subcommand {
    ($name:expr, $module:ident) => (
        $module::build_ui(Runtime::get_default_cli_builder(
                $name,
                &version!()[..],
                $name))
    )
}

gen_types_buildui!(
    ("../imag-bookmark/src/ui.rs",  imagbookmark),
    ("../imag-counter/src/ui.rs",   imagcounter),
    ("../imag-diary/src/ui.rs",     imagdiary),
    ("../imag-link/src/ui.rs",      imaglink),
    ("../imag-notes/src/ui.rs",     imagnotes),
    ("../imag-ref/src/ui.rs",       imagref),
    ("../imag-store/src/ui.rs",     imagstore),
    ("../imag-tag/src/ui.rs",       imagtag),
    ("../imag-todo/src/ui.rs",      imagtodo),
    ("../imag-view/src/ui.rs",      imagview)
);

fn main() {
    let mut app = Runtime::get_default_cli_builder(
        "imag",
        &version!()[..],
        "imag")
        .subcommand(build_subcommand!("bookmark",   imagbookmark))
        .subcommand(build_subcommand!("counter",    imagcounter))
        .subcommand(build_subcommand!("diary",      imagdiary))
        .subcommand(build_subcommand!("link",       imaglink))
        .subcommand(build_subcommand!("notes",      imagnotes))
        .subcommand(build_subcommand!("ref",        imagref))
        .subcommand(build_subcommand!("store",      imagstore))
        .subcommand(build_subcommand!("tag",        imagtag))
        .subcommand(build_subcommand!("todo",       imagtodo))
        .subcommand(build_subcommand!("view",       imagview));

    app.gen_completions("imag", Shell::Bash, env!("OUT_DIR"));
    app.gen_completions("imag", Shell::Fish, env!("OUT_DIR"));
    app.gen_completions("imag", Shell::Zsh, env!("OUT_DIR"));

}

<|endoftext|>


<commit_before>#![allow(
    clippy::diverging_sub_expression,
    clippy::let_and_return,
    clippy::let_underscore_drop,
    clippy::never_loop,
    clippy::unit_arg
)]

use anyhow::{anyhow, ensure, Chain, Error, Result};
use std::fmt::Debug;
use std::iter;
use std::marker::PhantomData;
use std::ops::Add;

struct S;

impl<T> Add<T> for S {
    type Output = bool;
    fn add(self, rhs: T) -> Self::Output {
        let _ = rhs;
        false
    }
}

trait Trait: Sized {
    fn t(self, i: i32) -> i32 {
        i
    }
}

impl<T> Trait for T {}

#[track_caller]
fn assert_err<T: Debug>(result: impl FnOnce() -> Result<T>, expected: &'static str) {
    let actual = result().unwrap_err().to_string();

    let mut accepted_alternatives = expected.split('\n');
    let expected = accepted_alternatives.next_back().unwrap();
    if accepted_alternatives.any(|alternative| actual == alternative) {
        return;
    }

    assert_eq!(actual, expected);
}

#[test]
fn test_recursion() {
    // Must not blow the default #[recursion_limit], which is 128.
    #[rustfmt::skip]
    let test = || Ok(ensure!(
        false | false | false | false | false | false | false | false | false |
        false | false | false | false | false | false | false | false | false |
        false | false | false | false | false | false | false | false | false |
        false | false | false | false | false | false | false | false | false |
        false | false | false | false | false | false | false | false | false |
        false | false | false | false | false | false | false | false | false |
        false | false | false | false | false | false | false | false | false
    ));

    test().unwrap_err();
}

#[test]
fn test_low_precedence_control_flow() {
    #[allow(unreachable_code)]
    let test = || {
        let val = loop {
            // Break has lower precedence than the comparison operators so the
            // expression here is `S + (break (1 == 1))`. It would be bad if the
            // ensure macro partitioned this input into `(S + break 1) == (1)`
            // because that means a different thing than what was written.
            ensure!(S + break 1 == 1);
        };
        Ok(val)
    };

    assert!(test().unwrap());
}

#[test]
fn test_low_precedence_binary_operator() {
    // Must not partition as `false == (true && false)`.
    let test = || Ok(ensure!(false == true && false));
    assert_err(test, "Condition failed: `false == true && false`");

    // But outside the root level, it is fine.
    let test = || Ok(ensure!(while false == true && false {} < ()));
    assert_err(
        test,
        "Condition failed: `while false == true && false { } < ()` (() vs ())",
    );
}

#[test]
fn test_closure() {
    // Must not partition as `(S + move) || (1 == 1)` by treating move as an
    // identifier, nor as `(S + move || 1) == (1)` by misinterpreting the
    // closure precedence.
    let test = || Ok(ensure!(S + move || 1 == 1));
    assert_err(test, "Condition failed: `S + (move || 1 == 1)`");

    let test = || Ok(ensure!(S + || 1 == 1));
    assert_err(test, "Condition failed: `S + (|| 1 == 1)`");

    // Must not partition as `S + ((move | ()) | 1) == 1` by treating those
    // pipes as bitwise-or.
    let test = || Ok(ensure!(S + move |()| 1 == 1));
    assert_err(test, "Condition failed: `S + (move |()| 1 == 1)`");

    let test = || Ok(ensure!(S + |()| 1 == 1));
    assert_err(test, "Condition failed: `S + (|()| 1 == 1)`");
}

#[test]
fn test_unary() {
    let mut x = &1;
    let test = || Ok(ensure!(*x == 2));
    assert_err(test, "Condition failed: `*x == 2` (1 vs 2)");

    let test = || Ok(ensure!(!x == 1));
    assert_err(test, "Condition failed: `!x == 1` (-2 vs 1)");

    let test = || Ok(ensure!(-x == 1));
    assert_err(test, "Condition failed: `-x == 1` (-1 vs 1)");

    let test = || Ok(ensure!(&x == &&2));
    assert_err(test, "Condition failed: `&x == &&2` (1 vs 2)");

    let test = || Ok(ensure!(&mut x == *&&mut &2));
    assert_err(test, "Condition failed: `&mut x == *&&mut &2` (1 vs 2)");
}

#[test]
fn test_if() {
    #[rustfmt::skip]
    let test = || Ok(ensure!(if false {}.t(1) == 2));
    assert_err(test, "Condition failed: `if false { }.t(1) == 2` (1 vs 2)");

    #[rustfmt::skip]
    let test = || Ok(ensure!(if false {} else {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `if false { } else { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(if false {} else if false {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `if false { } else if false { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(if let 1 = 2 {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `if let 1 = 2 { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(if let 1 | 2 = 2 {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `if let 1 | 2 = 2 { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(if let | 1 | 2 = 2 {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `if let 1 | 2 = 2 { }.t(1) == 2` (1 vs 2)",
    );
}

#[test]
fn test_loop() {
    #[rustfmt::skip]
    let test = || Ok(ensure!(1 + loop { break 1 } == 1));
    assert_err(
        test,
        // 1.54 puts a double space after loop
        "Condition failed: `1 + loop  { break 1  } == 1` (2 vs 1)\n\
         Condition failed: `1 + loop { break 1  } == 1` (2 vs 1)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(1 + 'a: loop { break 'a 1 } == 1));
    assert_err(
        test,
        // 1.54 puts a double space after loop
        "Condition failed: `1 + 'a: loop  { break 'a 1  } == 1` (2 vs 1)\n\
         Condition failed: `1 + 'a: loop { break 'a 1  } == 1` (2 vs 1)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(while false {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `while false { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(while let None = Some(1) {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `while let None = Some(1) { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(for _x in iter::once(0) {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `for _x in iter::once(0) { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(for | _x in iter::once(0) {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `for _x in iter::once(0) { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(for true | false in iter::empty() {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `for true | false in iter::empty() { }.t(1) == 2` (1 vs 2)",
    );
}

#[test]
fn test_match() {
    #[rustfmt::skip]
    let test = || Ok(ensure!(match 1 == 1 { true => 1, false => 0 } == 2));
    assert_err(
        test,
        "Condition failed: `match 1 == 1 { true => 1, false => 0, } == 2` (1 vs 2)",
    );
}

#[test]
fn test_atom() {
    let test = || Ok(ensure!([false, false].len() > 3));
    assert_err(
        test,
        "Condition failed: `[false, false].len() > 3` (2 vs 3)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!({ let x = 1; x } >= 3));
    assert_err(test, "Condition failed: `{ let x = 1; x } >= 3` (1 vs 3)");

    let test = || Ok(ensure!(S + async { 1 } == true));
    assert_err(
        test,
        "Condition failed: `S + async  { 1 } == true` (false vs true)",
    );

    let test = || Ok(ensure!(S + async move { 1 } == true));
    assert_err(
        test,
        "Condition failed: `S + async move  { 1 } == true` (false vs true)",
    );

    let test = || Ok(ensure!(S + unsafe { 1 } == true));
    assert_err(
        test,
        "Condition failed: `S + unsafe { 1 } == true` (false vs true)",
    );
}

#[test]
fn test_path() {
    let test = || Ok(ensure!(crate::S.t(1) == 2));
    assert_err(test, "Condition failed: `crate::S.t(1) == 2` (1 vs 2)");

    let test = || Ok(ensure!(::anyhow::Error::root_cause.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `::anyhow::Error::root_cause.t(1) == 2` (1 vs 2)",
    );

    let test = || Ok(ensure!(Error::msg::<&str>.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `Error::msg::<&str>.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(Error::msg::<&str,>.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `Error::msg::<&str>.t(1) == 2` (1 vs 2)",
    );

    let test = || Ok(ensure!(Error::msg::<<str as ToOwned>::Owned>.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `Error::msg::<<str as ToOwned>::Owned>.t(1) == 2` (1 vs 2)",
    );

    let test = || Ok(ensure!(Chain::<'static>::new.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `Chain::<'static>::new.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(Chain::<'static,>::new.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `Chain::<'static>::new.t(1) == 2` (1 vs 2)",
    );
}

#[test]
fn test_macro() {
    let test = || Ok(ensure!(anyhow!("...").to_string().len() <= 1));
    assert_err(
        test,
        "Condition failed: `anyhow!(\"...\").to_string().len() <= 1` (3 vs 1)",
    );

    let test = || Ok(ensure!(vec![1].len() < 1));
    assert_err(test, "Condition failed: `vec![1].len() < 1` (1 vs 1)");

    let test = || Ok(ensure!(stringify! {} != ""));
    assert_err(
        test,
        "Condition failed: `stringify! { } != \"\"` (\"\" vs \"\")",
    );
}

#[test]
fn test_trailer() {
    let test = || Ok(ensure!((|| 1)() == 2));
    assert_err(test, "Condition failed: `(|| 1)() == 2` (1 vs 2)");

    let test = || Ok(ensure!(b"hmm"[1] == b'c'));
    assert_err(test, "Condition failed: `b\"hmm\"[1] == b'c'` (109 vs 99)");

    let test = || Ok(ensure!(PhantomData::<u8> {} != PhantomData));
    assert_err(
        test,
        "Condition failed: `PhantomData::<u8>{} != PhantomData` (PhantomData vs PhantomData)",
    );

    let result = Ok::<_, Error>(1);
    let test = || Ok(ensure!(result? == 2));
    assert_err(test, "Condition failed: `result? == 2` (1 vs 2)");

    let test = || Ok(ensure!((2, 3).1 == 2));
    assert_err(test, "Condition failed: `(2, 3).1 == 2` (3 vs 2)");

    let err = anyhow!("");
    let test = || Ok(ensure!(err.is::<&str>() == false));
    assert_err(
        test,
        "Condition failed: `err.is::<&str>() == false` (true vs false)",
    );

    let test = || Ok(ensure!(err.is::<<str as ToOwned>::Owned>() == true));
    assert_err(
        test,
        "Condition failed: `err.is::<<str as ToOwned>::Owned>() == true` (false vs true)",
    );
}

#[test]
fn test_too_long() {
    let test = || Ok(ensure!("" == "x".repeat(10)));
    assert_err(
        test,
        "Condition failed: `\"\" == \"x\".repeat(10)` (\"\" vs \"xxxxxxxxxx\")",
    );

    let test = || Ok(ensure!("" == "x".repeat(80)));
    assert_err(test, "Condition failed: `\"\" == \"x\".repeat(80)`");
}
<commit_msg>Add test of newlines in ensure debug<commit_after>#![allow(
    clippy::diverging_sub_expression,
    clippy::let_and_return,
    clippy::let_underscore_drop,
    clippy::never_loop,
    clippy::unit_arg
)]

use anyhow::{anyhow, ensure, Chain, Error, Result};
use std::fmt::Debug;
use std::iter;
use std::marker::PhantomData;
use std::ops::Add;

struct S;

impl<T> Add<T> for S {
    type Output = bool;
    fn add(self, rhs: T) -> Self::Output {
        let _ = rhs;
        false
    }
}

trait Trait: Sized {
    fn t(self, i: i32) -> i32 {
        i
    }
}

impl<T> Trait for T {}

#[track_caller]
fn assert_err<T: Debug>(result: impl FnOnce() -> Result<T>, expected: &'static str) {
    let actual = result().unwrap_err().to_string();

    let mut accepted_alternatives = expected.split('\n');
    let expected = accepted_alternatives.next_back().unwrap();
    if accepted_alternatives.any(|alternative| actual == alternative) {
        return;
    }

    assert_eq!(actual, expected);
}

#[test]
fn test_recursion() {
    // Must not blow the default #[recursion_limit], which is 128.
    #[rustfmt::skip]
    let test = || Ok(ensure!(
        false | false | false | false | false | false | false | false | false |
        false | false | false | false | false | false | false | false | false |
        false | false | false | false | false | false | false | false | false |
        false | false | false | false | false | false | false | false | false |
        false | false | false | false | false | false | false | false | false |
        false | false | false | false | false | false | false | false | false |
        false | false | false | false | false | false | false | false | false
    ));

    test().unwrap_err();
}

#[test]
fn test_low_precedence_control_flow() {
    #[allow(unreachable_code)]
    let test = || {
        let val = loop {
            // Break has lower precedence than the comparison operators so the
            // expression here is `S + (break (1 == 1))`. It would be bad if the
            // ensure macro partitioned this input into `(S + break 1) == (1)`
            // because that means a different thing than what was written.
            ensure!(S + break 1 == 1);
        };
        Ok(val)
    };

    assert!(test().unwrap());
}

#[test]
fn test_low_precedence_binary_operator() {
    // Must not partition as `false == (true && false)`.
    let test = || Ok(ensure!(false == true && false));
    assert_err(test, "Condition failed: `false == true && false`");

    // But outside the root level, it is fine.
    let test = || Ok(ensure!(while false == true && false {} < ()));
    assert_err(
        test,
        "Condition failed: `while false == true && false { } < ()` (() vs ())",
    );
}

#[test]
fn test_closure() {
    // Must not partition as `(S + move) || (1 == 1)` by treating move as an
    // identifier, nor as `(S + move || 1) == (1)` by misinterpreting the
    // closure precedence.
    let test = || Ok(ensure!(S + move || 1 == 1));
    assert_err(test, "Condition failed: `S + (move || 1 == 1)`");

    let test = || Ok(ensure!(S + || 1 == 1));
    assert_err(test, "Condition failed: `S + (|| 1 == 1)`");

    // Must not partition as `S + ((move | ()) | 1) == 1` by treating those
    // pipes as bitwise-or.
    let test = || Ok(ensure!(S + move |()| 1 == 1));
    assert_err(test, "Condition failed: `S + (move |()| 1 == 1)`");

    let test = || Ok(ensure!(S + |()| 1 == 1));
    assert_err(test, "Condition failed: `S + (|()| 1 == 1)`");
}

#[test]
fn test_unary() {
    let mut x = &1;
    let test = || Ok(ensure!(*x == 2));
    assert_err(test, "Condition failed: `*x == 2` (1 vs 2)");

    let test = || Ok(ensure!(!x == 1));
    assert_err(test, "Condition failed: `!x == 1` (-2 vs 1)");

    let test = || Ok(ensure!(-x == 1));
    assert_err(test, "Condition failed: `-x == 1` (-1 vs 1)");

    let test = || Ok(ensure!(&x == &&2));
    assert_err(test, "Condition failed: `&x == &&2` (1 vs 2)");

    let test = || Ok(ensure!(&mut x == *&&mut &2));
    assert_err(test, "Condition failed: `&mut x == *&&mut &2` (1 vs 2)");
}

#[test]
fn test_if() {
    #[rustfmt::skip]
    let test = || Ok(ensure!(if false {}.t(1) == 2));
    assert_err(test, "Condition failed: `if false { }.t(1) == 2` (1 vs 2)");

    #[rustfmt::skip]
    let test = || Ok(ensure!(if false {} else {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `if false { } else { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(if false {} else if false {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `if false { } else if false { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(if let 1 = 2 {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `if let 1 = 2 { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(if let 1 | 2 = 2 {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `if let 1 | 2 = 2 { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(if let | 1 | 2 = 2 {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `if let 1 | 2 = 2 { }.t(1) == 2` (1 vs 2)",
    );
}

#[test]
fn test_loop() {
    #[rustfmt::skip]
    let test = || Ok(ensure!(1 + loop { break 1 } == 1));
    assert_err(
        test,
        // 1.54 puts a double space after loop
        "Condition failed: `1 + loop  { break 1  } == 1` (2 vs 1)\n\
         Condition failed: `1 + loop { break 1  } == 1` (2 vs 1)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(1 + 'a: loop { break 'a 1 } == 1));
    assert_err(
        test,
        // 1.54 puts a double space after loop
        "Condition failed: `1 + 'a: loop  { break 'a 1  } == 1` (2 vs 1)\n\
         Condition failed: `1 + 'a: loop { break 'a 1  } == 1` (2 vs 1)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(while false {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `while false { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(while let None = Some(1) {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `while let None = Some(1) { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(for _x in iter::once(0) {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `for _x in iter::once(0) { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(for | _x in iter::once(0) {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `for _x in iter::once(0) { }.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(for true | false in iter::empty() {}.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `for true | false in iter::empty() { }.t(1) == 2` (1 vs 2)",
    );
}

#[test]
fn test_match() {
    #[rustfmt::skip]
    let test = || Ok(ensure!(match 1 == 1 { true => 1, false => 0 } == 2));
    assert_err(
        test,
        "Condition failed: `match 1 == 1 { true => 1, false => 0, } == 2` (1 vs 2)",
    );
}

#[test]
fn test_atom() {
    let test = || Ok(ensure!([false, false].len() > 3));
    assert_err(
        test,
        "Condition failed: `[false, false].len() > 3` (2 vs 3)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!({ let x = 1; x } >= 3));
    assert_err(test, "Condition failed: `{ let x = 1; x } >= 3` (1 vs 3)");

    let test = || Ok(ensure!(S + async { 1 } == true));
    assert_err(
        test,
        "Condition failed: `S + async  { 1 } == true` (false vs true)",
    );

    let test = || Ok(ensure!(S + async move { 1 } == true));
    assert_err(
        test,
        "Condition failed: `S + async move  { 1 } == true` (false vs true)",
    );

    let test = || Ok(ensure!(S + unsafe { 1 } == true));
    assert_err(
        test,
        "Condition failed: `S + unsafe { 1 } == true` (false vs true)",
    );
}

#[test]
fn test_path() {
    let test = || Ok(ensure!(crate::S.t(1) == 2));
    assert_err(test, "Condition failed: `crate::S.t(1) == 2` (1 vs 2)");

    let test = || Ok(ensure!(::anyhow::Error::root_cause.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `::anyhow::Error::root_cause.t(1) == 2` (1 vs 2)",
    );

    let test = || Ok(ensure!(Error::msg::<&str>.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `Error::msg::<&str>.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(Error::msg::<&str,>.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `Error::msg::<&str>.t(1) == 2` (1 vs 2)",
    );

    let test = || Ok(ensure!(Error::msg::<<str as ToOwned>::Owned>.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `Error::msg::<<str as ToOwned>::Owned>.t(1) == 2` (1 vs 2)",
    );

    let test = || Ok(ensure!(Chain::<'static>::new.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `Chain::<'static>::new.t(1) == 2` (1 vs 2)",
    );

    #[rustfmt::skip]
    let test = || Ok(ensure!(Chain::<'static,>::new.t(1) == 2));
    assert_err(
        test,
        "Condition failed: `Chain::<'static>::new.t(1) == 2` (1 vs 2)",
    );
}

#[test]
fn test_macro() {
    let test = || Ok(ensure!(anyhow!("...").to_string().len() <= 1));
    assert_err(
        test,
        "Condition failed: `anyhow!(\"...\").to_string().len() <= 1` (3 vs 1)",
    );

    let test = || Ok(ensure!(vec![1].len() < 1));
    assert_err(test, "Condition failed: `vec![1].len() < 1` (1 vs 1)");

    let test = || Ok(ensure!(stringify! {} != ""));
    assert_err(
        test,
        "Condition failed: `stringify! { } != \"\"` (\"\" vs \"\")",
    );
}

#[test]
fn test_trailer() {
    let test = || Ok(ensure!((|| 1)() == 2));
    assert_err(test, "Condition failed: `(|| 1)() == 2` (1 vs 2)");

    let test = || Ok(ensure!(b"hmm"[1] == b'c'));
    assert_err(test, "Condition failed: `b\"hmm\"[1] == b'c'` (109 vs 99)");

    let test = || Ok(ensure!(PhantomData::<u8> {} != PhantomData));
    assert_err(
        test,
        "Condition failed: `PhantomData::<u8>{} != PhantomData` (PhantomData vs PhantomData)",
    );

    let result = Ok::<_, Error>(1);
    let test = || Ok(ensure!(result? == 2));
    assert_err(test, "Condition failed: `result? == 2` (1 vs 2)");

    let test = || Ok(ensure!((2, 3).1 == 2));
    assert_err(test, "Condition failed: `(2, 3).1 == 2` (3 vs 2)");

    let err = anyhow!("");
    let test = || Ok(ensure!(err.is::<&str>() == false));
    assert_err(
        test,
        "Condition failed: `err.is::<&str>() == false` (true vs false)",
    );

    let test = || Ok(ensure!(err.is::<<str as ToOwned>::Owned>() == true));
    assert_err(
        test,
        "Condition failed: `err.is::<<str as ToOwned>::Owned>() == true` (false vs true)",
    );
}

#[test]
fn test_whitespace() {
    #[derive(Debug)]
    pub struct Point {
        pub x: i32,
        pub y: i32,
    }

    let point = Point { x: 0, y: 0 };
    let test = || Ok(ensure!("" == format!("{:#?}", point)));
    assert_err(test, "Condition failed: `\"\" == format!(\"{:#?}\", point)` (\"\" vs \"Point {\\n    x: 0,\\n    y: 0,\\n}\")");
}

#[test]
fn test_too_long() {
    let test = || Ok(ensure!("" == "x".repeat(10)));
    assert_err(
        test,
        "Condition failed: `\"\" == \"x\".repeat(10)` (\"\" vs \"xxxxxxxxxx\")",
    );

    let test = || Ok(ensure!("" == "x".repeat(80)));
    assert_err(test, "Condition failed: `\"\" == \"x\".repeat(80)`");
}
<|endoftext|>


<commit_before>extern crate winapi;
extern crate user32;
extern crate kernel32;
extern crate direct2d;

use std::{ptr, mem};
use std::ffi::OsStr;
use std::os::windows::ffi::OsStrExt;
use winapi::*;
use direct2d::{Factory, RenderTarget};
use direct2d::render_target::RenderTargetBacking;
use direct2d::math::ColorF;

struct Window {
    hwnd: HWND,
    factory: Factory,
    target: Option<RenderTarget>,
}

struct WindowCreate {
    props: D2D1_RENDER_TARGET_PROPERTIES,
    hprops: D2D1_HWND_RENDER_TARGET_PROPERTIES,
}

unsafe impl RenderTargetBacking for WindowCreate {
    fn create_target(self, factory: &mut ID2D1Factory) -> Result<*mut ID2D1RenderTarget, HRESULT> {
        unsafe {
            let mut ptr: *mut ID2D1HwndRenderTarget = ptr::null_mut();
            let hr = factory.CreateHwndRenderTarget(
                &self.props,
                &self.hprops,
                &mut ptr as *mut _,
            );

            let ptr: *mut _ = &mut **ptr;

            if SUCCEEDED(hr) {
                Ok(ptr)
            } else {
                Err(From::from(hr))
            }
        }
    }
}

unsafe extern "system" fn wnd_proc(hwnd: HWND, msg: UINT, wp: WPARAM, lp: LPARAM) -> LRESULT {
    match msg {
        WM_CREATE => {
            // Set the window pointer into the creation parameters
            let cs: &CREATESTRUCTW = mem::transmute(lp);
            user32::SetWindowLongPtrW(hwnd, GWLP_USERDATA, mem::transmute(cs.lpCreateParams));

            // Create the direct2d stuff
            let params = WindowCreate {
                props: D2D1_RENDER_TARGET_PROPERTIES {
                    _type: D2D1_RENDER_TARGET_TYPE_DEFAULT,
                    pixelFormat: D2D1_PIXEL_FORMAT {
                        format: DXGI_FORMAT_UNKNOWN,
                        alphaMode: D2D1_ALPHA_MODE_UNKNOWN,
                    },
                    dpiX: 0.0,
                    dpiY: 0.0,
                    usage: D2D1_RENDER_TARGET_USAGE_NONE,
                    minLevel: D2D1_FEATURE_LEVEL_DEFAULT,
                },
                hprops: D2D1_HWND_RENDER_TARGET_PROPERTIES {
                    hwnd: hwnd,
                    pixelSize: D2D1_SIZE_U {
                        width: 800,
                        height: 480,
                    },
                    presentOptions: D2D1_PRESENT_OPTIONS_NONE,
                },
            };

            let window: &mut Window = mem::transmute(cs.lpCreateParams);
            window.target = Some(window.factory.create_render_target(params).unwrap());

            0
        },
        WM_PAINT => {
            let window: &mut Window = mem::transmute(user32::GetWindowLongPtrW(hwnd, GWLP_USERDATA));
            let rt = window.target.as_mut().unwrap();

            rt.begin_draw();
            rt.clear(&ColorF::uint_rgb(0xFF0000, 1.0));
            rt.end_draw().unwrap();

            user32::DefWindowProcW(hwnd, msg, wp, lp)
        },
        WM_TIMER => {
            user32::DestroyWindow(hwnd);

            0
        },
        _ => user32::DefWindowProcW(hwnd, msg, wp, lp)
    }
}

unsafe fn real_window_test() {
    let factory = Factory::create().unwrap();

    let mut window = Window {
        hwnd: ptr::null_mut(),
        factory: factory,
        target: None,
    };

    let hinst: HINSTANCE = kernel32::GetModuleHandleW(ptr::null());
    let class_name = "Test D2D1 Window Class".to_wide_null();
    let window_name = "Test D2D1 Window".to_wide_null();

    user32::RegisterClassW(&WNDCLASSW {
        style: CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW,
        lpfnWndProc: Some(wnd_proc),
        cbWndExtra: mem::size_of::<&mut Window>() as c_int,
        hInstance: hinst,
        lpszClassName: class_name.as_ptr(),

        .. mem::zeroed()
    });

    let hwnd = user32::CreateWindowExW(
        0, // dwExStyle
        class_name.as_ptr(),
        window_name.as_ptr(),
        WS_OVERLAPPED,
        CW_USEDEFAULT, // x
        CW_USEDEFAULT, // y
        800, // width
        480, // height
        ptr::null_mut(),
        ptr::null_mut(),
        hinst,
        &mut window as *mut _ as LPVOID,
    );

    assert!(hwnd != ptr::null_mut());
    window.hwnd = hwnd;

    user32::ShowWindow(hwnd, SW_SHOW);
    user32::SetTimer(hwnd, 0, 1000, None);

    let mut msg: MSG = mem::uninitialized();
    loop {
        match user32::GetMessageW(&mut msg, hwnd, 0, 0) {
            -1 => break,
            _ => {
                user32::TranslateMessage(&msg);
                user32::DispatchMessageW(&msg);
            }
        }
    }
}

#[test]
fn window_test() {
    unsafe { real_window_test() };
}

pub trait ToWide {
    fn to_wide(&self) -> Vec<u16>;
    fn to_wide_null(&self) -> Vec<u16>;
}

impl<T> ToWide for T where T: AsRef<OsStr> {
    fn to_wide(&self) -> Vec<u16> {
        self.as_ref().encode_wide().collect()
    }
    fn to_wide_null(&self) -> Vec<u16> {
        self.as_ref().encode_wide().chain(Some(0)).collect()
    }
}

<commit_msg>Still working, just shifted a line<commit_after>extern crate winapi;
extern crate user32;
extern crate kernel32;
extern crate direct2d;

use std::{ptr, mem};
use std::ffi::OsStr;
use std::os::windows::ffi::OsStrExt;
use winapi::*;
use direct2d::{Factory, RenderTarget};
use direct2d::render_target::RenderTargetBacking;
use direct2d::math::ColorF;

struct Window {
    hwnd: HWND,
    factory: Factory,
    target: Option<RenderTarget>,
}

struct WindowCreate {
    props: D2D1_RENDER_TARGET_PROPERTIES,
    hprops: D2D1_HWND_RENDER_TARGET_PROPERTIES,
}

unsafe impl RenderTargetBacking for WindowCreate {
    fn create_target(self, factory: &mut ID2D1Factory) -> Result<*mut ID2D1RenderTarget, HRESULT> {
        unsafe {
            let mut ptr: *mut ID2D1HwndRenderTarget = ptr::null_mut();
            let hr = factory.CreateHwndRenderTarget(
                &self.props,
                &self.hprops,
                &mut ptr as *mut _,
            );

            let ptr: *mut _ = &mut **ptr;

            if SUCCEEDED(hr) {
                Ok(ptr)
            } else {
                Err(From::from(hr))
            }
        }
    }
}

unsafe extern "system" fn wnd_proc(hwnd: HWND, msg: UINT, wp: WPARAM, lp: LPARAM) -> LRESULT {
    match msg {
        WM_CREATE => {
            // Set the window pointer into the creation parameters
            let cs: &CREATESTRUCTW = mem::transmute(lp);
            user32::SetWindowLongPtrW(hwnd, GWLP_USERDATA, mem::transmute(cs.lpCreateParams));

            // Create the direct2d stuff
            let params = WindowCreate {
                props: D2D1_RENDER_TARGET_PROPERTIES {
                    _type: D2D1_RENDER_TARGET_TYPE_DEFAULT,
                    pixelFormat: D2D1_PIXEL_FORMAT {
                        format: DXGI_FORMAT_UNKNOWN,
                        alphaMode: D2D1_ALPHA_MODE_UNKNOWN,
                    },
                    dpiX: 0.0,
                    dpiY: 0.0,
                    usage: D2D1_RENDER_TARGET_USAGE_NONE,
                    minLevel: D2D1_FEATURE_LEVEL_DEFAULT,
                },
                hprops: D2D1_HWND_RENDER_TARGET_PROPERTIES {
                    hwnd: hwnd,
                    pixelSize: D2D1_SIZE_U {
                        width: 800,
                        height: 480,
                    },
                    presentOptions: D2D1_PRESENT_OPTIONS_NONE,
                },
            };

            let window: &mut Window = mem::transmute(cs.lpCreateParams);
            window.target = Some(window.factory.create_render_target(params).unwrap());

            0
        },
        WM_PAINT => {
            let window: &mut Window = mem::transmute(user32::GetWindowLongPtrW(hwnd, GWLP_USERDATA));

            let rt = window.target.as_mut().unwrap();
            rt.begin_draw();
            rt.clear(&ColorF::uint_rgb(0xFF0000, 1.0));
            rt.end_draw().unwrap();

            user32::DefWindowProcW(hwnd, msg, wp, lp)
        },
        WM_TIMER => {
            user32::DestroyWindow(hwnd);

            0
        },
        _ => user32::DefWindowProcW(hwnd, msg, wp, lp)
    }
}

unsafe fn real_window_test() {
    let factory = Factory::create().unwrap();

    let mut window = Window {
        hwnd: ptr::null_mut(),
        factory: factory,
        target: None,
    };

    let hinst: HINSTANCE = kernel32::GetModuleHandleW(ptr::null());
    let class_name = "Test D2D1 Window Class".to_wide_null();
    let window_name = "Test D2D1 Window".to_wide_null();

    user32::RegisterClassW(&WNDCLASSW {
        style: CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW,
        lpfnWndProc: Some(wnd_proc),
        cbWndExtra: mem::size_of::<&mut Window>() as c_int,
        hInstance: hinst,
        lpszClassName: class_name.as_ptr(),

        .. mem::zeroed()
    });

    let hwnd = user32::CreateWindowExW(
        0, // dwExStyle
        class_name.as_ptr(),
        window_name.as_ptr(),
        WS_OVERLAPPED,
        CW_USEDEFAULT, // x
        CW_USEDEFAULT, // y
        800, // width
        480, // height
        ptr::null_mut(),
        ptr::null_mut(),
        hinst,
        &mut window as *mut _ as LPVOID,
    );

    assert!(hwnd != ptr::null_mut());
    window.hwnd = hwnd;

    user32::ShowWindow(hwnd, SW_SHOW);
    user32::SetTimer(hwnd, 0, 1000, None);

    let mut msg: MSG = mem::uninitialized();
    loop {
        match user32::GetMessageW(&mut msg, hwnd, 0, 0) {
            -1 => break,
            _ => {
                user32::TranslateMessage(&msg);
                user32::DispatchMessageW(&msg);
            }
        }
    }
}

#[test]
fn window_test() {
    unsafe { real_window_test() };
}

pub trait ToWide {
    fn to_wide(&self) -> Vec<u16>;
    fn to_wide_null(&self) -> Vec<u16>;
}

impl<T> ToWide for T where T: AsRef<OsStr> {
    fn to_wide(&self) -> Vec<u16> {
        self.as_ref().encode_wide().collect()
    }
    fn to_wide_null(&self) -> Vec<u16> {
        self.as_ref().encode_wide().chain(Some(0)).collect()
    }
}

<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

extern crate regex;

use regex::Regex;
use std::env;
use std::fs::File;
use std::io::{BufRead, BufReader, Write};
use std::path::Path;

fn main() {
    if std::mem::size_of::<Option<bool>>() == 1 {
         // https://github.com/rust-lang/rust/pull/45225
         println!("cargo:rustc-cfg=rustc_has_pr45225")
    }

    let root_path = Path::new("../../../");
    let bindings_file = root_path.join("components/style/gecko/generated/bindings.rs");
    let glue_file = root_path.join("ports/geckolib/glue.rs");

    println!("cargo:rerun-if-changed=build.rs");
    println!("cargo:rerun-if-changed={}", glue_file.display());
    println!("cargo:rerun-if-changed={}", bindings_file.display());

    let env_out_dir = env::var("OUT_DIR").unwrap();
    let out_dir = Path::new(&env_out_dir);

    {
        let output = out_dir.join("check_bindings.rs");
        let r = BufReader::new(File::open(bindings_file).unwrap());
        let mut w = File::create(output).unwrap();

        w.write_all(b"fn assert_types() {\n").unwrap();

        let matcher = Regex::new(r"fn\s*Servo_([a-zA-Z0-9_]+)\s*\(").unwrap();

        for line in r.lines() {
            let s = line.unwrap();
            for cap in matcher.captures_iter(&s) {
                w.write_all(format!("    [ Servo_{0}, bindings::Servo_{0} ];\n", &cap[1]).as_bytes()).unwrap();
            }
        }

        w.write_all(b"}\n").unwrap();
    }

    {
        let output = out_dir.join("glue.rs");
        let r = BufReader::new(File::open(glue_file).unwrap());
        let mut w = File::create(output).unwrap();

        w.write_all(b"pub use style::gecko::arc_types::*;\n").unwrap();

        for line in r.lines() {
            let s = line.unwrap().replace("pub extern \"C\" fn", "pub unsafe extern \"C\" fn");
            w.write_all(s.as_bytes()).unwrap();
            w.write_all(b"\n").unwrap();
        }
    }

    // https://github.com/rust-lang/cargo/issues/3544
    let style_out_dir = env::var_os("DEP_FOR SOME REASON THE LINKS KEY IS REQUIRED \
                                     TO PASS DATA AROUND BETWEEN BUILD SCRIPTS_OUT_DIR").unwrap();
    File::create(out_dir.join("bindings.rs"))
        .unwrap()
        .write_all(format!("include!(concat!({:?}, \"/gecko/structs.rs\"));",
                           style_out_dir).as_bytes())
        .unwrap();

    if env::var_os("MOZ_SRC").is_some() {
        println!("cargo:rustc-cfg=linking_with_gecko")
    }
}
<commit_msg>style: Skip a function for the static tests.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

extern crate regex;

use regex::Regex;
use std::env;
use std::fs::File;
use std::io::{BufRead, BufReader, Write};
use std::path::Path;

fn main() {
    if std::mem::size_of::<Option<bool>>() == 1 {
         // https://github.com/rust-lang/rust/pull/45225
         println!("cargo:rustc-cfg=rustc_has_pr45225")
    }

    let root_path = Path::new("../../../");
    let bindings_file = root_path.join("components/style/gecko/generated/bindings.rs");
    let glue_file = root_path.join("ports/geckolib/glue.rs");

    println!("cargo:rerun-if-changed=build.rs");
    println!("cargo:rerun-if-changed={}", glue_file.display());
    println!("cargo:rerun-if-changed={}", bindings_file.display());

    let env_out_dir = env::var("OUT_DIR").unwrap();
    let out_dir = Path::new(&env_out_dir);

    {
        let output = out_dir.join("check_bindings.rs");
        let r = BufReader::new(File::open(bindings_file).unwrap());
        let mut w = File::create(output).unwrap();

        w.write_all(b"fn assert_types() {\n").unwrap();

        let matcher = Regex::new(r"fn\s*Servo_([a-zA-Z0-9_]+)\s*\(").unwrap();

        for line in r.lines() {
            let s = line.unwrap();
            for cap in matcher.captures_iter(&s) {
                // This causes a mismatch in old libclangs (the ones that are
                // used in linux32 mozilla-central) because it generates:
                //
                //   *const nsTArray<*const RawServoStyleSet>
                //
                // Instead of:
                //
                //   *const nsTArray<RawServoStyleSetBorrowed>
                //
                // Which is not a problem, but would cause this to not compile.
                //
                // Skip this until libclang is updated there.
                if &cap[1] == "InvalidateStyleForDocStateChanges" {
                    continue;
                }
                w.write_all(format!("    [ Servo_{0}, bindings::Servo_{0} ];\n", &cap[1]).as_bytes()).unwrap();
            }
        }

        w.write_all(b"}\n").unwrap();
    }

    {
        let output = out_dir.join("glue.rs");
        let r = BufReader::new(File::open(glue_file).unwrap());
        let mut w = File::create(output).unwrap();

        w.write_all(b"pub use style::gecko::arc_types::*;\n").unwrap();

        for line in r.lines() {
            let s = line.unwrap().replace("pub extern \"C\" fn", "pub unsafe extern \"C\" fn");
            w.write_all(s.as_bytes()).unwrap();
            w.write_all(b"\n").unwrap();
        }
    }

    // https://github.com/rust-lang/cargo/issues/3544
    let style_out_dir = env::var_os("DEP_FOR SOME REASON THE LINKS KEY IS REQUIRED \
                                     TO PASS DATA AROUND BETWEEN BUILD SCRIPTS_OUT_DIR").unwrap();
    File::create(out_dir.join("bindings.rs"))
        .unwrap()
        .write_all(format!("include!(concat!({:?}, \"/gecko/structs.rs\"));",
                           style_out_dir).as_bytes())
        .unwrap();

    if env::var_os("MOZ_SRC").is_some() {
        println!("cargo:rustc-cfg=linking_with_gecko")
    }
}
<|endoftext|>


<commit_before>/// `Builder!` macro
///
/// Only useful in combination with [custom_derive][custom_derive].
///
/// [custom_derive]: https://crates.io/crates/custom_derive
#[macro_export]
#[doc(hidden)]
macro_rules! Builder {
    // Strip empty argument list if given (Passed by custom_derive macro)
    (() $($body:tt)*) => {
        Builder! { $($body)* }
    };

    // Strip meta items, pub (if present) and struct from definition
    (
        $(#[$ignore:meta])*
        $(pub)* struct $($body:tt)*
    ) => {
        Builder! { $($body)* }
    };

    // Struct with generics.
    //
    // Receive parsed fields of normal struct from `__parse_struct_body`
    // and add implementation.
    //
    // These patterns must appear above those which start with an ident to
    // compile.
    (
        (
            struct_name = $struct_name:ident,
            generics = ($($generics:ident),*),
        ),
        fields = [$({
            field_name: $field_name:ident,
            field_ty: $field_ty:ty,
            field_attr: [$($attr:tt)*],
        })+],
    ) => {
        #[allow(dead_code)]
        impl<$($generics),*> $struct_name<$($generics),*> {
            $(
                $($attr)*
                pub fn $field_name<VALUE: Into<$field_ty>>(mut self, value: VALUE) -> Self {
                    self.$field_name = value.into();
                    self
                }
            )+
        }
    };

    // Struct without generics.
    //
    // Receive parsed fields of normal struct from `__parse_struct_body`
    // and add implementation.
    //
    // These patterns must appear above those which start with an ident to
    // compile.
    (
        (
            struct_name = $struct_name:ident,
            generics = (),
        ),
        fields = [$({
            field_name: $field_name:ident,
            field_ty: $field_ty:ty,
            field_attr: [$($attr:tt)*],
        })+],
    ) => {
        #[allow(dead_code)]
        impl $struct_name {
            $(
                $($attr)*
                pub fn $field_name<VALUE: Into<$field_ty>>(mut self, value: VALUE) -> Self {
                    self.$field_name = value.into();
                    self
                }
            )+
        }
    };

    // Handle struct with generics
    (
        $struct_name:ident <$($generics:ident),*>
        $body:tt $(;)*
    ) => {
        __parse_struct_body! {
            (
                struct_name = $struct_name,
                generics = ($($generics),*),
            ),
            callback = Builder,
            body = $body,
        }
    };

    // Handle struct with no generics
    (
        $struct_name:ident
        $body:tt $(;)*
    ) => {
        __parse_struct_body! {
            (
                struct_name = $struct_name,
                generics = (),
            ),
            callback = Builder,
            body = $body,
        }
    };
}
<commit_msg>simplify macro<commit_after>/// `Builder!` macro
///
/// Only useful in combination with [custom_derive][custom_derive].
///
/// [custom_derive]: https://crates.io/crates/custom_derive
#[macro_export]
#[doc(hidden)]
macro_rules! Builder {
    // Strip empty argument list if given (Passed by custom_derive macro)
    (() $($body:tt)*) => {
        Builder! { $($body)* }
    };

    // Strip meta items, pub (if present) and struct from definition
    (
        $(#[$ignore:meta])*
        $(pub)* struct $($body:tt)*
    ) => {
        Builder! { $($body)* }
    };

    // Struct with + without generics.
    //
    // Receive parsed fields of normal struct from `__parse_struct_body`
    // and add implementation.
    //
    // These patterns must appear above those which start with an ident to
    // compile.
    (
        (
            struct_name = $struct_name:ident,
            generics = ($($generics:ident),*),
        ),
        fields = [$({
            field_name: $field_name:ident,
            field_ty: $field_ty:ty,
            field_attr: [$($attr:tt)*],
        })+],
    ) => {
        #[allow(dead_code)]
        impl<$($generics),*> $struct_name<$($generics),*> {
            $(
                $($attr)*
                pub fn $field_name<VALUE: Into<$field_ty>>(mut self, value: VALUE) -> Self {
                    self.$field_name = value.into();
                    self
                }
            )+
        }
    };

    // Handle struct with generics
    (
        $struct_name:ident <$($generics:ident),*>
        $body:tt $(;)*
    ) => {
        __parse_struct_body! {
            (
                struct_name = $struct_name,
                generics = ($($generics),*),
            ),
            callback = Builder,
            body = $body,
        }
    };

    // Handle struct with no generics
    (
        $struct_name:ident
        $body:tt $(;)*
    ) => {
        __parse_struct_body! {
            (
                struct_name = $struct_name,
                generics = (),
            ),
            callback = Builder,
            body = $body,
        }
    };
}
<|endoftext|>


<commit_before>// Copyright (c) 2017, All Contributors (see CONTRIBUTORS file)
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#[macro_use]
extern crate try_opt;
extern crate viewdb_core;

pub(crate) use viewdb_core::{TraitPattern, TraitResolver};
#[cfg(test)]
pub(crate) use viewdb_core::{Trait};

mod condition;
pub use condition::{Condition, Value};

#[cfg(test)]
mod tests {
    use super::{Value, Trait, TraitResolver, Condition};
    use super::Condition::{Equal};
    use condition::processing::{Processor, TraitsExpansion, PresentEqualCompaction,
                                ComparisonSuppression, BooleanLiteralSuppression};

    #[derive(Clone)]
    pub struct Test<T : AsRef<[u8]> + Clone>((T, Trait<T>), (T, Trait<T>), (T, Trait<T>));

    impl<T : AsRef<[u8]> + Clone> TraitResolver<T> for Test<T>  {
        fn resolve(&self, name: T) -> &Trait<T> {
            if name.as_ref() == (self.0).0.as_ref() {
                return &(self.0).1
            }
            if name.as_ref() == (self.1).0.as_ref() {
                return &(self.1).1
            }
            if name.as_ref() == (self.2).0.as_ref() {
                return &(self.2).1
            }
            unreachable!()
        }
    }

    #[test]
    fn it_works() {
        let cond =
            Condition::fact(
                Condition::trait_scope("Object", Equal(Value::Attribute("https://viewdb.org/attributes#object"), Value::Data("123")))
                .and(Condition::trait_scope("NameChanged", Equal(Value::Attribute("https://viewdb.org/attributes#value"), Value::Binding("Name"))))
                .and(Condition::trait_scope("Timestamp", Equal(Value::Attribute("https://viewdb.org/attributes#timestamp"), Value::Binding("Timestamp"))))
            );

        let object = vec![("https://viewdb.org/attributes#object", None).into()].into();
        let name_changed = vec![("https://viewdb.org/attributes#factType", Some("NameChanged")).into(),
                                      ("https://viewdb.org/attributes#value", None).into()].into();
        let timestamp = vec![("https://viewdb.org/attributes#timestamp", None).into()].into();

        let te = TraitsExpansion::new(Test(("Object", object), ("NameChanged", name_changed), ("Timestamp", timestamp)));

        let cond1 = BooleanLiteralSuppression.process(ComparisonSuppression.process(PresentEqualCompaction.process(te.process(cond).unwrap()).unwrap()).unwrap()).unwrap();
        println!("{:#?}", cond1);
    }
}
<commit_msg>Problem: viewdb_query's condition module is not public<commit_after>// Copyright (c) 2017, All Contributors (see CONTRIBUTORS file)
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#[macro_use]
extern crate try_opt;
extern crate viewdb_core;

pub(crate) use viewdb_core::{TraitPattern, TraitResolver};
#[cfg(test)]
pub(crate) use viewdb_core::{Trait};

pub mod condition;
pub use condition::{Condition, Value};

#[cfg(test)]
mod tests {
    use super::{Value, Trait, TraitResolver, Condition};
    use super::Condition::{Equal};
    use condition::processing::{Processor, TraitsExpansion, PresentEqualCompaction,
                                ComparisonSuppression, BooleanLiteralSuppression};

    #[derive(Clone)]
    pub struct Test<T : AsRef<[u8]> + Clone>((T, Trait<T>), (T, Trait<T>), (T, Trait<T>));

    impl<T : AsRef<[u8]> + Clone> TraitResolver<T> for Test<T>  {
        fn resolve(&self, name: T) -> &Trait<T> {
            if name.as_ref() == (self.0).0.as_ref() {
                return &(self.0).1
            }
            if name.as_ref() == (self.1).0.as_ref() {
                return &(self.1).1
            }
            if name.as_ref() == (self.2).0.as_ref() {
                return &(self.2).1
            }
            unreachable!()
        }
    }

    #[test]
    fn it_works() {
        let cond =
            Condition::fact(
                Condition::trait_scope("Object", Equal(Value::Attribute("https://viewdb.org/attributes#object"), Value::Data("123")))
                .and(Condition::trait_scope("NameChanged", Equal(Value::Attribute("https://viewdb.org/attributes#value"), Value::Binding("Name"))))
                .and(Condition::trait_scope("Timestamp", Equal(Value::Attribute("https://viewdb.org/attributes#timestamp"), Value::Binding("Timestamp"))))
            );

        let object = vec![("https://viewdb.org/attributes#object", None).into()].into();
        let name_changed = vec![("https://viewdb.org/attributes#factType", Some("NameChanged")).into(),
                                      ("https://viewdb.org/attributes#value", None).into()].into();
        let timestamp = vec![("https://viewdb.org/attributes#timestamp", None).into()].into();

        let te = TraitsExpansion::new(Test(("Object", object), ("NameChanged", name_changed), ("Timestamp", timestamp)));

        let cond1 = BooleanLiteralSuppression.process(ComparisonSuppression.process(PresentEqualCompaction.process(te.process(cond).unwrap()).unwrap()).unwrap()).unwrap();
        println!("{:#?}", cond1);
    }
}
<|endoftext|>


<commit_before>use std::process;
use std::os::unix::io::{RawFd, AsRawFd};

pub struct PersistentChild {
    cmd: &'static str,
    pub child : process::Child,
}

impl PersistentChild {
    fn spawn(cmd: &str) -> process::Child {
        process::Command::new(cmd)
                .stdin(process::Stdio::piped())
                .stdout(process::Stdio::piped())
                .stderr(process::Stdio::piped())
                .spawn()
                .expect("failed to execute process")
    }

    pub fn new(cmd: &'static str) -> Self {
        let child_proc = Self::spawn(cmd);
        //TODO, if I want to reuse the pipes, I need to keep them open and need to write my custom
        //child spawner -_-
        // If I keep both ends of the pipes open in the main process, I will not be able to read an
        // EOF if the child closes its end of the pipe. Probabaly I stick to the std library and
        //  create new pipes when a child needs to be respawned

        println!("spawned child with pid {}", child_proc.id());
        PersistentChild{ cmd: cmd, child: child_proc }
    }

    pub fn respawn(&mut self) {
        self.child = Self::spawn(self.cmd);
    }

    pub fn stdin_as_mut(&mut self) -> &mut process::ChildStdin {
        self.child.stdin.as_mut().unwrap()
    }

    pub fn stdout_as_mut(&mut self) -> &mut process::ChildStdout {
        self.child.stdout.as_mut().unwrap()
    }

    pub fn stderr_as_mut(&mut self) -> &mut process::ChildStderr {
        self.child.stderr.as_mut().unwrap()
    }

    fn _unwrap_as_raw_fd<T: AsRawFd>(x: &Option<T>) -> RawFd {
        assert!(x.is_some());
        x.as_ref().unwrap().as_raw_fd()
    }

    pub fn is_stdin(&self, i: RawFd) -> bool {
        Self::_unwrap_as_raw_fd(&self.child.stdin) == i
    }

    pub fn is_stdout(&self, i: RawFd) -> bool {
        Self::_unwrap_as_raw_fd(&self.child.stdout) == i
    }

    pub fn is_stderr(&self, i: RawFd) -> bool {
        Self::_unwrap_as_raw_fd(&self.child.stderr) == i
    }

    // returns immediately, does not reap!
    // Child not modified.
    pub fn has_terminated(&self) -> bool{
        let pid = self.child.id();
        ffi::has_terminated(pid)
    }
}

mod ffi{
    use libc::{c_int, pid_t, uid_t, idtype_t, id_t, SIGCHLD};
    use std::mem;

    extern {
        fn waitid(idtype: idtype_t, id: id_t, infop: *mut siginfo_t, options: c_int) -> c_int;
    }

    struct siginfo_t {
        pub si_signo: c_int,
        pub si_errno: c_int,
        pub si_code: c_int,
        pub si_trapno: c_int,
        pub si_pid: pid_t,
        pub si_uid: uid_t,
        pub si_status: c_int,
        pub _pad: [c_int; 25],
        // some fields omitted
    }

    pub fn has_terminated(pid: u32) -> bool {
        //let pid = pid as id_t; // std::process::Child::id returns u32 is pid
        //let pid = pid ad id_t;

        assert_eq!(mem::size_of::<siginfo_t>(), sizeof_siginfo_t);

        let mut info: siginfo_t = unsafe { mem::zeroed() };
        let infop: *mut siginfo_t = &mut info;
        let ret = unsafe { waitid(waitpid_P_PID, pid, infop, waitpidoptions_WNOHANG | waitpidoptions_WEXITED | waitpidoptions_WNOWAIT) };
        assert_eq!(ret, 0);
        if info.si_pid != 0 {
            assert_eq!(info.si_pid, pid as pid_t);
            assert_eq!(info.si_signo, SIGCHLD);
            true
        }else{
            false
        }
    }

    #[link(name = "cppdefs", kind="static")]
    extern {
        static sizeof_siginfo_t: usize;

        static waitpidoptions_WNOHANG: c_int;
        static waitpidoptions_WUNTRACED: c_int;
        static waitpidoptions_WCONTINUED: c_int;
        static waitpidoptions_WEXITED: c_int;
        static waitpidoptions_WSTOPPED: c_int;
        static waitpidoptions_WNOWAIT: c_int;

        static waitpid_P_PID: idtype_t;
    }
}
<commit_msg>force struct layout as in C<commit_after>use std::process;
use std::os::unix::io::{RawFd, AsRawFd};

pub struct PersistentChild {
    cmd: &'static str,
    pub child : process::Child,
}

impl PersistentChild {
    fn spawn(cmd: &str) -> process::Child {
        process::Command::new(cmd)
                .stdin(process::Stdio::piped())
                .stdout(process::Stdio::piped())
                .stderr(process::Stdio::piped())
                .spawn()
                .expect("failed to execute process")
    }

    pub fn new(cmd: &'static str) -> Self {
        let child_proc = Self::spawn(cmd);
        //TODO, if I want to reuse the pipes, I need to keep them open and need to write my custom
        //child spawner -_-
        // If I keep both ends of the pipes open in the main process, I will not be able to read an
        // EOF if the child closes its end of the pipe. Probabaly I stick to the std library and
        //  create new pipes when a child needs to be respawned

        println!("spawned child with pid {}", child_proc.id());
        PersistentChild{ cmd: cmd, child: child_proc }
    }

    pub fn respawn(&mut self) {
        self.child = Self::spawn(self.cmd);
    }

    pub fn stdin_as_mut(&mut self) -> &mut process::ChildStdin {
        self.child.stdin.as_mut().unwrap()
    }

    pub fn stdout_as_mut(&mut self) -> &mut process::ChildStdout {
        self.child.stdout.as_mut().unwrap()
    }

    pub fn stderr_as_mut(&mut self) -> &mut process::ChildStderr {
        self.child.stderr.as_mut().unwrap()
    }

    fn _unwrap_as_raw_fd<T: AsRawFd>(x: &Option<T>) -> RawFd {
        assert!(x.is_some());
        x.as_ref().unwrap().as_raw_fd()
    }

    pub fn is_stdin(&self, i: RawFd) -> bool {
        Self::_unwrap_as_raw_fd(&self.child.stdin) == i
    }

    pub fn is_stdout(&self, i: RawFd) -> bool {
        Self::_unwrap_as_raw_fd(&self.child.stdout) == i
    }

    pub fn is_stderr(&self, i: RawFd) -> bool {
        Self::_unwrap_as_raw_fd(&self.child.stderr) == i
    }

    // returns immediately, does not reap!
    // Child not modified.
    pub fn has_terminated(&self) -> bool{
        let pid = self.child.id();
        ffi::has_terminated(pid)
    }
}

mod ffi{
    use libc::{c_int, pid_t, uid_t, idtype_t, id_t, SIGCHLD};
    use std::mem;

    extern {
        fn waitid(idtype: idtype_t, id: id_t, infop: *mut siginfo_t, options: c_int) -> c_int;
    }

    #[repr(C)]
    struct siginfo_t {
        pub si_signo: c_int,
        pub si_errno: c_int,
        pub si_code: c_int,
        pub si_trapno: c_int,
        pub si_pid: pid_t,
        pub si_uid: uid_t,
        pub si_status: c_int,
        pub _pad: [c_int; 25],
        // some fields omitted
    }

    pub fn has_terminated(pid: u32) -> bool {
        //let pid = pid as id_t; // std::process::Child::id returns u32 is pid
        //let pid = pid ad id_t;

        assert_eq!(mem::size_of::<siginfo_t>(), sizeof_siginfo_t);

        let mut info: siginfo_t = unsafe { mem::zeroed() };
        let infop: *mut siginfo_t = &mut info;
        let ret = unsafe { waitid(waitpid_P_PID, pid, infop, waitpidoptions_WNOHANG | waitpidoptions_WEXITED | waitpidoptions_WNOWAIT) };
        assert_eq!(ret, 0);
        if info.si_pid != 0 {
            assert_eq!(info.si_pid, pid as pid_t);
            assert_eq!(info.si_signo, SIGCHLD);
            true
        }else{
            false
        }
    }

    #[link(name = "cppdefs", kind="static")]
    extern {
        static sizeof_siginfo_t: usize;

        static waitpidoptions_WNOHANG: c_int;
        static waitpidoptions_WUNTRACED: c_int;
        static waitpidoptions_WCONTINUED: c_int;
        static waitpidoptions_WEXITED: c_int;
        static waitpidoptions_WSTOPPED: c_int;
        static waitpidoptions_WNOWAIT: c_int;

        static waitpid_P_PID: idtype_t;
    }
}
<|endoftext|>


<commit_before>use rustc::lint::*;

use crate::utils::{in_macro, match_type, paths, span_lint_and_then, usage::is_potentially_mutated};
use rustc::hir::intravisit::*;
use rustc::hir::*;
use syntax::ast::NodeId;
use syntax::codemap::Span;

/// **What it does:** Checks for calls of unwrap[_err]() that cannot fail.
///
/// **Why is this bad?** Using `if let` or `match` is more idiomatic.
///
/// **Known problems:** Limitations of the borrow checker might make unwrap() necessary sometimes?
///
/// **Example:**
/// ```rust
/// if option.is_some() {
///     do_something_with(option.unwrap())
/// }
/// ```
///
/// Could be written:
///
/// ```rust
/// if let Some(value) = option {
///     do_something_with(value)
/// }
/// ```
declare_clippy_lint! {
    pub UNNECESSARY_UNWRAP,
    nursery,
    "checks for calls of unwrap[_err]() that cannot fail"
}

/// **What it does:** Checks for calls of unwrap[_err]() that will always fail.
///
/// **Why is this bad?** If panicking is desired, an explicit `panic!()` should be used.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// if option.is_none() {
///     do_something_with(option.unwrap())
/// }
/// ```
///
/// This code will always panic. The if condition should probably be inverted.
/// ```
declare_clippy_lint! {
    pub PANICKING_UNWRAP,
    nursery,
    "checks for calls of unwrap[_err]() that will always fail"
}

pub struct Pass;

/// Visitor that keeps track of which variables are unwrappable.
struct UnwrappableVariablesVisitor<'a, 'tcx: 'a> {
    unwrappables: Vec<UnwrapInfo<'tcx>>,
    cx: &'a LateContext<'a, 'tcx>,
}
/// Contains information about whether a variable can be unwrapped.
#[derive(Copy, Clone, Debug)]
struct UnwrapInfo<'tcx> {
    /// The variable that is checked
    ident: &'tcx Path,
    /// The check, like `x.is_ok()`
    check: &'tcx Expr,
    /// Whether `is_some()` or `is_ok()` was called (as opposed to `is_err()` or `is_none()`).
    safe_to_unwrap: bool,
}

/// Collects the information about unwrappable variables from an if condition
/// The `invert` argument tells us whether the condition is negated.
fn collect_unwrap_info<'a, 'tcx: 'a>(
    cx: &'a LateContext<'a, 'tcx>,
    expr: &'tcx Expr,
    invert: bool,
) -> Vec<UnwrapInfo<'tcx>> {
    if let Expr_::ExprBinary(op, left, right) = &expr.node {
        match (invert, op.node) {
            (false, BinOp_::BiAnd) | (false, BinOp_::BiBitAnd) | (true, BinOp_::BiOr) | (true, BinOp_::BiBitOr) => {
                let mut unwrap_info = collect_unwrap_info(cx, left, invert);
                unwrap_info.append(&mut collect_unwrap_info(cx, right, invert));
                return unwrap_info;
            },
            _ => (),
        }
    } else if let Expr_::ExprUnary(UnNot, expr) = &expr.node {
        return collect_unwrap_info(cx, expr, !invert);
    } else {
        if_chain! {
            if let Expr_::ExprMethodCall(method_name, _, args) = &expr.node;
            if let Expr_::ExprPath(QPath::Resolved(None, path)) = &args[0].node;
            let ty = cx.tables.expr_ty(&args[0]);
            if match_type(cx, ty, &paths::OPTION) || match_type(cx, ty, &paths::RESULT);
            let name = method_name.name.as_str();
            if ["is_some", "is_none", "is_ok", "is_err"].contains(&&*name);
            then {
                assert!(args.len() == 1);
                let unwrappable = match name.as_ref() {
                    "is_some" | "is_ok" => true,
                    "is_err" | "is_none" => false,
                    _ => unreachable!(),
                };
                let safe_to_unwrap = unwrappable != invert;
                return vec![UnwrapInfo { ident: path, check: expr, safe_to_unwrap }];
            }
        }
    }
    Vec::new()
}

impl<'a, 'tcx: 'a> UnwrappableVariablesVisitor<'a, 'tcx> {
    fn visit_branch(&mut self, cond: &'tcx Expr, branch: &'tcx Expr, else_branch: bool) {
        let prev_len = self.unwrappables.len();
        for unwrap_info in collect_unwrap_info(self.cx, cond, else_branch) {
            if is_potentially_mutated(unwrap_info.ident, cond, self.cx)
                || is_potentially_mutated(unwrap_info.ident, branch, self.cx)
            {
                // if the variable is mutated, we don't know whether it can be unwrapped:
                continue;
            }
            self.unwrappables.push(unwrap_info);
        }
        walk_expr(self, branch);
        self.unwrappables.truncate(prev_len);
    }
}

impl<'a, 'tcx: 'a> Visitor<'tcx> for UnwrappableVariablesVisitor<'a, 'tcx> {
    fn visit_expr(&mut self, expr: &'tcx Expr) {
        if let Expr_::ExprIf(cond, then, els) = &expr.node {
            walk_expr(self, cond);
            self.visit_branch(cond, then, false);
            if let Some(els) = els {
                self.visit_branch(cond, els, true);
            }
        } else {
            // find `unwrap[_err]()` calls:
            if_chain! {
                if let Expr_::ExprMethodCall(ref method_name, _, ref args) = expr.node;
                if let Expr_::ExprPath(QPath::Resolved(None, ref path)) = args[0].node;
                if ["unwrap", "unwrap_err"].contains(&&*method_name.name.as_str());
                let call_to_unwrap = method_name.name == "unwrap";
                if let Some(unwrappable) = self.unwrappables.iter()
                    .find(|u| u.ident.def == path.def);
                then {
                    if call_to_unwrap == unwrappable.safe_to_unwrap {
                        span_lint_and_then(
                            self.cx,
                            UNNECESSARY_UNWRAP,
                            expr.span,
                            &format!("You checked before that `{}()` cannot fail. \
                            Instead of checking and unwrapping, it's better to use `if let` or `match`.",
                            method_name.name),
                            |db| { db.span_label(unwrappable.check.span, "the check is happening here"); },
                        );
                    } else {
                        span_lint_and_then(
                            self.cx,
                            UNNECESSARY_UNWRAP,
                            expr.span,
                            &format!("This call to `{}()` will always panic.",
                            method_name.name),
                            |db| { db.span_label(unwrappable.check.span, "because of this check"); },
                        );
                    }
                }
            }
            walk_expr(self, expr);
        }
    }

    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
        NestedVisitorMap::OnlyBodies(&self.cx.tcx.hir)
    }
}

impl<'a> LintPass for Pass {
    fn get_lints(&self) -> LintArray {
        lint_array!(UNNECESSARY_UNWRAP)
    }
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
    fn check_fn(
        &mut self,
        cx: &LateContext<'a, 'tcx>,
        kind: FnKind<'tcx>,
        decl: &'tcx FnDecl,
        body: &'tcx Body,
        span: Span,
        fn_id: NodeId,
    ) {
        if in_macro(span) {
            return;
        }

        let mut v = UnwrappableVariablesVisitor {
            cx,
            unwrappables: Vec::new(),
        };

        walk_fn(&mut v, kind, decl, body.id(), span, fn_id);
    }
}
<commit_msg>Update known problems.<commit_after>use rustc::lint::*;

use crate::utils::{in_macro, match_type, paths, span_lint_and_then, usage::is_potentially_mutated};
use rustc::hir::intravisit::*;
use rustc::hir::*;
use syntax::ast::NodeId;
use syntax::codemap::Span;

/// **What it does:** Checks for calls of unwrap[_err]() that cannot fail.
///
/// **Why is this bad?** Using `if let` or `match` is more idiomatic.
///
/// **Known problems:** Limitations of the borrow checker might make unwrap() necessary sometimes?
///
/// **Example:**
/// ```rust
/// if option.is_some() {
///     do_something_with(option.unwrap())
/// }
/// ```
///
/// Could be written:
///
/// ```rust
/// if let Some(value) = option {
///     do_something_with(value)
/// }
/// ```
declare_clippy_lint! {
    pub UNNECESSARY_UNWRAP,
    nursery,
    "checks for calls of unwrap[_err]() that cannot fail"
}

/// **What it does:** Checks for calls of unwrap[_err]() that will always fail.
///
/// **Why is this bad?** If panicking is desired, an explicit `panic!()` should be used.
///
/// **Known problems:** This lint only checks `if` conditions not assignments.
/// So something like `let x: Option<()> = None; x.unwrap();` will not be recognized.
///
/// **Example:**
/// ```rust
/// if option.is_none() {
///     do_something_with(option.unwrap())
/// }
/// ```
///
/// This code will always panic. The if condition should probably be inverted.
/// ```
declare_clippy_lint! {
    pub PANICKING_UNWRAP,
    nursery,
    "checks for calls of unwrap[_err]() that will always fail"
}

pub struct Pass;

/// Visitor that keeps track of which variables are unwrappable.
struct UnwrappableVariablesVisitor<'a, 'tcx: 'a> {
    unwrappables: Vec<UnwrapInfo<'tcx>>,
    cx: &'a LateContext<'a, 'tcx>,
}
/// Contains information about whether a variable can be unwrapped.
#[derive(Copy, Clone, Debug)]
struct UnwrapInfo<'tcx> {
    /// The variable that is checked
    ident: &'tcx Path,
    /// The check, like `x.is_ok()`
    check: &'tcx Expr,
    /// Whether `is_some()` or `is_ok()` was called (as opposed to `is_err()` or `is_none()`).
    safe_to_unwrap: bool,
}

/// Collects the information about unwrappable variables from an if condition
/// The `invert` argument tells us whether the condition is negated.
fn collect_unwrap_info<'a, 'tcx: 'a>(
    cx: &'a LateContext<'a, 'tcx>,
    expr: &'tcx Expr,
    invert: bool,
) -> Vec<UnwrapInfo<'tcx>> {
    if let Expr_::ExprBinary(op, left, right) = &expr.node {
        match (invert, op.node) {
            (false, BinOp_::BiAnd) | (false, BinOp_::BiBitAnd) | (true, BinOp_::BiOr) | (true, BinOp_::BiBitOr) => {
                let mut unwrap_info = collect_unwrap_info(cx, left, invert);
                unwrap_info.append(&mut collect_unwrap_info(cx, right, invert));
                return unwrap_info;
            },
            _ => (),
        }
    } else if let Expr_::ExprUnary(UnNot, expr) = &expr.node {
        return collect_unwrap_info(cx, expr, !invert);
    } else {
        if_chain! {
            if let Expr_::ExprMethodCall(method_name, _, args) = &expr.node;
            if let Expr_::ExprPath(QPath::Resolved(None, path)) = &args[0].node;
            let ty = cx.tables.expr_ty(&args[0]);
            if match_type(cx, ty, &paths::OPTION) || match_type(cx, ty, &paths::RESULT);
            let name = method_name.name.as_str();
            if ["is_some", "is_none", "is_ok", "is_err"].contains(&&*name);
            then {
                assert!(args.len() == 1);
                let unwrappable = match name.as_ref() {
                    "is_some" | "is_ok" => true,
                    "is_err" | "is_none" => false,
                    _ => unreachable!(),
                };
                let safe_to_unwrap = unwrappable != invert;
                return vec![UnwrapInfo { ident: path, check: expr, safe_to_unwrap }];
            }
        }
    }
    Vec::new()
}

impl<'a, 'tcx: 'a> UnwrappableVariablesVisitor<'a, 'tcx> {
    fn visit_branch(&mut self, cond: &'tcx Expr, branch: &'tcx Expr, else_branch: bool) {
        let prev_len = self.unwrappables.len();
        for unwrap_info in collect_unwrap_info(self.cx, cond, else_branch) {
            if is_potentially_mutated(unwrap_info.ident, cond, self.cx)
                || is_potentially_mutated(unwrap_info.ident, branch, self.cx)
            {
                // if the variable is mutated, we don't know whether it can be unwrapped:
                continue;
            }
            self.unwrappables.push(unwrap_info);
        }
        walk_expr(self, branch);
        self.unwrappables.truncate(prev_len);
    }
}

impl<'a, 'tcx: 'a> Visitor<'tcx> for UnwrappableVariablesVisitor<'a, 'tcx> {
    fn visit_expr(&mut self, expr: &'tcx Expr) {
        if let Expr_::ExprIf(cond, then, els) = &expr.node {
            walk_expr(self, cond);
            self.visit_branch(cond, then, false);
            if let Some(els) = els {
                self.visit_branch(cond, els, true);
            }
        } else {
            // find `unwrap[_err]()` calls:
            if_chain! {
                if let Expr_::ExprMethodCall(ref method_name, _, ref args) = expr.node;
                if let Expr_::ExprPath(QPath::Resolved(None, ref path)) = args[0].node;
                if ["unwrap", "unwrap_err"].contains(&&*method_name.name.as_str());
                let call_to_unwrap = method_name.name == "unwrap";
                if let Some(unwrappable) = self.unwrappables.iter()
                    .find(|u| u.ident.def == path.def);
                then {
                    if call_to_unwrap == unwrappable.safe_to_unwrap {
                        span_lint_and_then(
                            self.cx,
                            UNNECESSARY_UNWRAP,
                            expr.span,
                            &format!("You checked before that `{}()` cannot fail. \
                            Instead of checking and unwrapping, it's better to use `if let` or `match`.",
                            method_name.name),
                            |db| { db.span_label(unwrappable.check.span, "the check is happening here"); },
                        );
                    } else {
                        span_lint_and_then(
                            self.cx,
                            UNNECESSARY_UNWRAP,
                            expr.span,
                            &format!("This call to `{}()` will always panic.",
                            method_name.name),
                            |db| { db.span_label(unwrappable.check.span, "because of this check"); },
                        );
                    }
                }
            }
            walk_expr(self, expr);
        }
    }

    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
        NestedVisitorMap::OnlyBodies(&self.cx.tcx.hir)
    }
}

impl<'a> LintPass for Pass {
    fn get_lints(&self) -> LintArray {
        lint_array!(UNNECESSARY_UNWRAP)
    }
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
    fn check_fn(
        &mut self,
        cx: &LateContext<'a, 'tcx>,
        kind: FnKind<'tcx>,
        decl: &'tcx FnDecl,
        body: &'tcx Body,
        span: Span,
        fn_id: NodeId,
    ) {
        if in_macro(span) {
            return;
        }

        let mut v = UnwrappableVariablesVisitor {
            cx,
            unwrappables: Vec::new(),
        };

        walk_fn(&mut v, kind, decl, body.id(), span, fn_id);
    }
}
<|endoftext|>