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)(auto ref 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 && isUserAggregate!(PointerTarget!T)) { 63 import python.type: pythonClass; 64 return pythonClass(value); 65 } 66 67 68 PyObject* toPython(T)(T value) if(is(Unqual!T == DateTime)) { 69 import python.raw: pyDateTimeFromDateAndTime; 70 return pyDateTimeFromDateAndTime(value.year, value.month, value.day, 71 value.hour, value.minute, value.second); 72 } 73 74 75 PyObject* toPython(T)(T value) if(is(Unqual!T == Date)) { 76 import python.raw: pyDateFromDate; 77 return pyDateFromDate(value.year, value.month, value.day); 78 } 79 80 81 PyObject* toPython(T)(T value) if(isSomeString!T) { 82 import python.raw: pyUnicodeFromStringAndSize; 83 import std.conv: to; 84 auto str = value.to!string; 85 return pyUnicodeFromStringAndSize(str.ptr, str.length); 86 } 87 88 89 PyObject* toPython(T)(T value) if(is(Unqual!T == bool)) { 90 import python.raw: PyBool_FromLong; 91 return PyBool_FromLong(value); 92 } 93 94 95 PyObject* toPython(T)(T value) if(isStaticArray!T) { 96 return toPython(value[]); 97 } 98 99 100 PyObject* toPython(T)(T value) if(isAssociativeArray!T) { 101 import python.raw: PyDict_New, PyDict_SetItem; 102 103 auto ret = PyDict_New; 104 105 foreach(k, v; value) { 106 PyDict_SetItem(ret, k.toPython, v.toPython); 107 } 108 109 return ret; 110 } 111 112 PyObject* toPython(T)(T value) if(isTuple!T) { 113 import python.raw: PyTuple_New, PyTuple_SetItem; 114 115 auto ret = PyTuple_New(value.length); 116 117 static foreach(i; 0 .. T.length) { 118 PyTuple_SetItem(ret, i, value[i].toPython); 119 } 120 121 return ret; 122 } 123 124 125 PyObject* toPython(T)(T value) if(isSomeChar!T) { 126 return null; // FIXME 127 } 128 129 130 PyObject* toPython(T)(T value) if(isCallable!T && !isUserAggregate!T) { 131 import python.type: pythonCallable; 132 return pythonCallable(value); 133 }