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, 8 isCallable, isSomeString; 9 import std.range: isInputRange; 10 import std.datetime: Date, DateTime; 11 12 13 PyObject* toPython(T)(T value) @trusted if(isIntegral!T) { 14 import python.raw: PyLong_FromLong; 15 return PyLong_FromLong(value); 16 } 17 18 19 PyObject* toPython(T)(T value) @trusted if(isFloatingPoint!T) { 20 import python.raw: PyFloat_FromDouble; 21 return PyFloat_FromDouble(value); 22 } 23 24 25 PyObject* toPython(T)(T value) if(isInputRange!T && !isSomeString!T && !isStaticArray!T) { 26 import python.raw: PyList_New, PyList_SetItem, PyList_Append; 27 import std.range: isForwardRange, enumerate; 28 29 static if(__traits(hasMember, T, "length")) { 30 const length = value.length; 31 enum append = false; 32 } else static if(isForwardRange!T){ 33 import std.range: walkLength; 34 import std.array: save; 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(isSomeString!T) { 81 import python.raw: pyUnicodeFromStringAndSize; 82 import std.conv: to; 83 auto str = value.to!string; 84 return pyUnicodeFromStringAndSize(str.ptr, str.length); 85 } 86 87 88 PyObject* toPython(T)(T value) if(is(Unqual!T == bool)) { 89 import python.raw: PyBool_FromLong; 90 return PyBool_FromLong(value); 91 } 92 93 94 PyObject* toPython(T)(T value) if(isStaticArray!T) { 95 return toPython(value[]); 96 } 97 98 99 PyObject* toPython(T)(T value) if(isAssociativeArray!T) { 100 import python.raw: PyDict_New, PyDict_SetItem; 101 102 auto ret = PyDict_New; 103 104 foreach(k, v; value) { 105 PyDict_SetItem(ret, k.toPython, v.toPython); 106 } 107 108 return ret; 109 } 110 111 PyObject* toPython(T)(T value) if(isTuple!T) { 112 import python.raw: PyTuple_New, PyTuple_SetItem; 113 114 auto ret = PyTuple_New(value.length); 115 116 static foreach(i; 0 .. T.length) { 117 PyTuple_SetItem(ret, i, value[i].toPython); 118 } 119 120 return ret; 121 } 122 123 124 PyObject* toPython(T)(T value) if(isSomeChar!T) { 125 return null; // FIXME 126 } 127 128 129 PyObject* toPython(T)(T value) if(isCallable!T && !isUserAggregate!T) { 130 import python.type: pythonCallable; 131 return pythonCallable(value); 132 }