<commit_before>use std::ffi::{CString, self};
use std::mem;
use std::str;
use libc::c_char;

use objc::{encode, Encode, Id};

use {INSCopying, INSObject};

pub trait INSValue : INSObject {
    type Value: Copy + Encode;

    fn value(&self) -> Self::Value {
        assert!(self.encoding() == encode::<Self::Value>());
        unsafe {
            let mut value = mem::uninitialized::<Self::Value>();
            let _: () = msg_send![self, getValue:&mut value];
            value
        }
    }

    fn encoding(&self) -> &str {
        unsafe {
            let result: *const c_char = msg_send![self, objCType];
            let bytes = ffi::c_str_to_bytes(&result);
            let s = str::from_utf8(bytes).unwrap();
            mem::transmute(s)
        }
    }

    fn from_value(value: Self::Value) -> Id<Self> {
        let cls = <Self as INSObject>::class();
        let encoding = CString::from_slice(encode::<Self::Value>().as_bytes());
        unsafe {
            let obj: *mut Self = msg_send![cls, alloc];
            let obj: *mut Self = msg_send![obj, initWithBytes:&value
                                                     objCType:encoding.as_ptr()];
            Id::from_retained_ptr(obj)
        }
    }
}

object_struct!(NSValue<T>);

impl<T> INSValue for NSValue<T> where T: Copy + Encode {
    type Value = T;
}

impl<T> INSCopying for NSValue<T> {
    type Output = NSValue<T>;
}

#[cfg(test)]
mod tests {
    use objc::{encode, Id};
    use {INSValue, NSValue};

    #[test]
    fn test_value() {
        let val: Id<NSValue<u32>> = INSValue::from_value(13);
        assert!(val.value() == 13);
        assert!(val.encoding() == encode::<u32>());
    }
}<commit_msg>Put a static bound on NSValue's value.<commit_after>use std::ffi::{CString, self};
use std::mem;
use std::str;
use libc::c_char;

use objc::{encode, Encode, Id};

use {INSCopying, INSObject};

pub trait INSValue : INSObject {
    type Value: 'static + Copy + Encode;

    fn value(&self) -> Self::Value {
        assert!(self.encoding() == encode::<Self::Value>());
        unsafe {
            let mut value = mem::uninitialized::<Self::Value>();
            let _: () = msg_send![self, getValue:&mut value];
            value
        }
    }

    fn encoding(&self) -> &str {
        unsafe {
            let result: *const c_char = msg_send![self, objCType];
            let bytes = ffi::c_str_to_bytes(&result);
            let s = str::from_utf8(bytes).unwrap();
            mem::transmute(s)
        }
    }

    fn from_value(value: Self::Value) -> Id<Self> {
        let cls = <Self as INSObject>::class();
        let encoding = CString::from_slice(encode::<Self::Value>().as_bytes());
        unsafe {
            let obj: *mut Self = msg_send![cls, alloc];
            let obj: *mut Self = msg_send![obj, initWithBytes:&value
                                                     objCType:encoding.as_ptr()];
            Id::from_retained_ptr(obj)
        }
    }
}

object_struct!(NSValue<T>);

impl<T> INSValue for NSValue<T> where T: 'static + Copy + Encode {
    type Value = T;
}

impl<T> INSCopying for NSValue<T> {
    type Output = NSValue<T>;
}

#[cfg(test)]
mod tests {
    use objc::{encode, Id};
    use {INSValue, NSValue};

    #[test]
    fn test_value() {
        let val: Id<NSValue<u32>> = INSValue::from_value(13);
        assert!(val.value() == 13);
        assert!(val.encoding() == encode::<u32>());
    }
}
{'fraction_non_alphanumeric': 0.1619574715991844, 'fraction_numerical': 0.0052432274978153216, 'mean_word_length': 2.3210831721470018, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '614499', 'n_tokens_mistral': 1140, 'n_tokens_neox': 1123, 'n_words': 252}