use std::ffi::c_int;

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
#[repr(C)]
pub struct Range {
    pub start: c_int,
    pub count: c_int,
}

impl Into<std::ops::Range<c_int>> for Range {
    fn into(self) -> std::ops::Range<c_int> {
        self.start..(self.start + self.count)
    }
}

impl From<std::ops::Range<c_int>> for Range {
    fn from(other: std::ops::Range<c_int>) -> Range {
        Range {
            start: other.start,
            count: other.end - other.start
        }
    }
}

#[cfg(test)]
mod test {
    use std::ffi::c_int;
    use super::Range;

    #[test]
    fn from_std_range() {
        assert_eq!(Range { start: 0, count: 10 }, Range::from(0..10));
        assert_eq!(Range { start: 1, count: 9 }, Range::from(1..10));
    }

    #[test]
    fn into_std_range() {
        assert_eq!(0..10, Into::<std::ops::Range<c_int>>::into(Range {
            start: 0,
            count: 10
        }));
        assert_eq!(1..10, Into::<std::ops::Range<c_int>>::into(Range {
            start: 1,
            count: 9
        }));
    }
}

pub mod ffi {
    use std::ffi::c_int;

    pub type WMRange = super::Range;

    #[unsafe(no_mangle)]
    pub extern "C" fn wmkrange(start: c_int, count: c_int) -> WMRange {
        WMRange { start, count }
    }
}
