1 module python.conv.d_to_python; 2 3 4 import python.raw: PyObject; 5 import python.type: isUserAggregate, isTuple, isNonRangeUDT; 6 import std.traits: Unqual, isIntegral, isFloatingPoint, isAggregateType, isArray, 7 isStaticArray, isAssociativeArray, isPointer, PointerTarget, isSomeChar, isCallable; 8 import std.range: isInputRange; 9 import std.datetime: Date, DateTime; 10 11 12 PyObject* toPython(T)(T value) @trusted if(isIntegral!T) { 13 import python.raw: PyLong_FromLong; 14 return PyLong_FromLong(value); 15 } 16 17 18 PyObject* toPython(T)(T value) @trusted if(isFloatingPoint!T) { 19 import python.raw: PyFloat_FromDouble; 20 return PyFloat_FromDouble(value); 21 } 22 23 24 PyObject* toPython(T)(T value) if(isInputRange!T && !is(T == string) && !isStaticArray!T) { 25 import python.raw: PyList_New, PyList_SetItem, PyList_Append; 26 import std.range: isForwardRange, enumerate; 27 28 static if(__traits(hasMember, T, "length")) { 29 const length = value.length; 30 enum append = false; 31 } else static if(isForwardRange!T){ 32 import std.range: walkLength; 33 import std.array: save; 34 static assert(isForwardRange!T); 35 const length = walkLength(value.save); 36 enum append = false; 37 } else { 38 enum length = 0; 39 enum append = true; 40 } 41 42 auto ret = PyList_New(length); 43 44 foreach(i, elt; value.enumerate) { 45 static if(append) 46 PyList_Append(ret, toPython(elt)); 47 else 48 PyList_SetItem(ret, i, toPython(elt)); 49 } 50 51 return ret; 52 53 } 54 55 56 PyObject* toPython(T)(T value) if(isNonRangeUDT!T) { 57 import python.type: pythonClass; 58 return pythonClass(value); 59 } 60 61 62 PyObject* toPython(T)(T value) if(isPointer!T && isNonRangeUDT!(PointerTarget!T)) { 63 return toPython(*value); 64 } 65 66 67 PyObject* toPython(T)(T value) if(is(Unqual!T == DateTime)) { 68 import python.raw: pyDateTimeFromDateAndTime; 69 return pyDateTimeFromDateAndTime(value.year, value.month, value.day, 70 value.hour, value.minute, value.second); 71 } 72 73 74 PyObject* toPython(T)(T value) if(is(Unqual!T == Date)) { 75 import python.raw: pyDateFromDate; 76 return pyDateFromDate(value.year, value.month, value.day); 77 } 78 79 80 PyObject* toPython(T)(T value) if(is(T == string)) { 81 import python.raw: pyUnicodeFromStringAndSize; 82 return pyUnicodeFromStringAndSize(value.ptr, value.length); 83 } 84 85 86 PyObject* toPython(T)(T value) if(is(Unqual!T == bool)) { 87 import python.raw: PyBool_FromLong; 88 return PyBool_FromLong(value); 89 } 90 91 92 PyObject* toPython(T)(T value) if(isStaticArray!T) { 93 return toPython(value[]); 94 } 95 96 97 PyObject* toPython(T)(T value) if(isAssociativeArray!T) { 98 import python.raw: PyDict_New, PyDict_SetItem; 99 100 auto ret = PyDict_New; 101 102 foreach(k, v; value) { 103 PyDict_SetItem(ret, k.toPython, v.toPython); 104 } 105 106 return ret; 107 } 108 109 PyObject* toPython(T)(T value) if(isTuple!T) { 110 import python.raw: PyTuple_New, PyTuple_SetItem; 111 112 auto ret = PyTuple_New(value.length); 113 114 static foreach(i; 0 .. T.length) { 115 PyTuple_SetItem(ret, i, value[i].toPython); 116 } 117 118 return ret; 119 } 120 121 122 PyObject* toPython(T)(T value) if(isSomeChar!T) { 123 return null; // FIXME 124 } 125 126 127 PyObject* toPython(T)(T value) if(isCallable!T && !isUserAggregate!T) { 128 import python.type: pythonCallable; 129 return pythonCallable(value); 130 }