1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
//! PyNone - Implementation of Singleton `None` Value
//!
//! ```ignore
//! None
//! ```
use std::borrow::Borrow;
use std::fmt;
use std::ops::Deref;

use runtime::Runtime;
use ::runtime::traits::{BooleanProvider, StringProvider};
use ::api::result::{ObjectResult, RtResult};
use api::selfref::{self, SelfRef};
use api::{RtValue, PyAPI, method, typing};

use ::system::primitives as rs;
use ::api::RtObject;
use ::modules::builtins::Type;


pub const NONE: &'static rs::None = &rs::None();
pub const NONE_STR: &'static str = "None";


pub struct PyNoneType {
    singleton_none: RtObject,
}


impl typing::BuiltinType for PyNoneType {
    type T = PyNone;
    type V = &'static rs::None;

    #[inline(always)]
    #[allow(unused_variables)]
    fn new(&self, rt: &Runtime, value: Self::V) -> RtObject {
        return self.singleton_none.clone();
    }

    fn init_type() -> Self {
        PyNoneType { singleton_none: PyNoneType::inject_selfref(PyNoneType::alloc(NONE)) }
    }

    fn inject_selfref(value: Self::T) -> RtObject {
        let object = RtObject::new(Type::None(value));
        let new = object.clone();

        match object.as_ref() {
            &Type::None(ref none) => {
                none.rc.set(&object.clone());
            }
            _ => unreachable!(),
        }
        new
    }

    fn alloc(value: Self::V) -> Self::T {
        PyNone {
            value: NoneValue(value, NONE_STR.to_string()),
            rc: selfref::RefCount::default(),
        }
    }
}


pub struct NoneValue(&'static rs::None, String);
pub type PyNone = RtValue<NoneValue>;



impl fmt::Display for PyNone {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "PyNone")
    }
}

impl fmt::Debug for PyNone {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "PyNone")
    }
}


impl PyAPI for PyNone {}


impl method::StringCast for PyNone {
    fn op_str(&self, rt: &Runtime) -> ObjectResult {
        Ok(rt.str(self.value.1.clone()))
    }

    fn native_str(&self) -> RtResult<rs::String> {
        Ok(self.value.1.clone())
    }
}


impl method::Equal for PyNone {
    fn op_eq(&self, rt: &Runtime, rhs: &RtObject) -> ObjectResult {
        let truth = self.native_eq(rhs.as_ref())?;
        Ok(rt.bool(truth))
    }

    fn native_eq(&self, rhs: &Type) -> RtResult<rs::Boolean> {
        match rhs {
            &Type::None(_) => Ok(true),
            _ => Ok(false),
        }
    }
}


impl method::BooleanCast for PyNone {
    fn op_bool(&self, rt: &Runtime) -> ObjectResult {
        Ok(rt.bool(false))
    }

    fn native_bool(&self) -> RtResult<rs::Boolean> {
        Ok(false)
    }
}


method_not_implemented!(PyNone,
    AbsValue   Add   AddItem   Append   Await   BitwiseAnd   BitwiseOr
    BytesCast   Call   Clear   Close   ComplexCast   Contains   Count   DelAttr
    Delete   DeleteItem   DescriptorGet   DescriptorSet
    DescriptorSetName   Discard   DivMod   Enter
    Exit   Extend   FloatCast    FloorDivision   Get   GetAttr   GetAttribute
    GetItem   GreaterOrEqual   GreaterThan   Hashed
    Id   InPlaceAdd   InPlaceBitwiseAnd   InPlaceBitwiseOr
    InPlaceDivMod   InPlaceFloorDivision   InPlaceLeftShift   InPlaceMatrixMultiply
    InPlaceModulus   InPlaceMultiply   InPlacePow   InPlaceRightShift
    InPlaceSubtract   InPlaceTrueDivision   InPlaceXOr   Index
    Init   IntegerCast   InvertValue   Is
    IsDisjoint   IsNot   Items   Iter    Keys   LeftShift   Length   LengthHint
    LessOrEqual   LessThan   MatrixMultiply   Modulus
    Multiply   NegateValue   New   Next    NotEqual   Pop   PopItem   PositiveValue
    Pow   ReflectedAdd   ReflectedBitwiseAnd   ReflectedBitwiseOr
    ReflectedDivMod   ReflectedFloorDivision   ReflectedLeftShift   ReflectedMatrixMultiply
    ReflectedModulus   ReflectedMultiply   ReflectedPow   ReflectedRightShift
    ReflectedSubtract   ReflectedTrueDivision   ReflectedXOr   Remove
    Reversed   RightShift   Rounding   Send    SetAttr   SetDefault   SetItem
    StringFormat   StringRepresentation   Subtract   Throw
    TrueDivision   Update   Values   XOr
);


#[cfg(test)]
mod tests {
    use ::runtime::Runtime;

    fn setup() -> (Runtime, ) {
        (Runtime::new(), )
    }

    #[test]
    fn stub() {
        info!("stub");
    }
}