Skip to content

Commit

Permalink
Code refactor and todo descriptions
Browse files Browse the repository at this point in the history
  • Loading branch information
Io-Maciek committed Jul 6, 2023
1 parent a0e8d59 commit bbb771d
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 112 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ __pycache__/

# C extensions
*.so
tests/

# Distribution / packaging
.Python
Expand Down
78 changes: 78 additions & 0 deletions IoDeSer/_DeSer/_IoDes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import inspect


class _IoDes:
@staticmethod
def read(ioStr, objType):
ioStr = _IoDes.__substring_brackets(ioStr)
primitive = (int, str, bool, float)
# print(objType)

if objType in primitive:
obj = objType(ioStr)
elif objType is list: # TODO
ioStr = _IoDes.__delete_tabs(ioStr)
lst = []
lines = ioStr.split('\n+\n')
for i in range(len(lines)):
lst.append(_IoDes.read(lines[i], str))
# TODO convert to proper element type, not 'str'
obj = lst
elif objType is tuple:
raise NotImplementedError("TUPLE NOT IMPLEMENTED YET")
elif inspect.isclass(objType): # TODO
try:
obj = objType()
except TypeError:
raise TypeError(
"Object of type " + str(objType) + " must have parameterless constructor or with default values.")
ioStr = _IoDes.__delete_tabs(ioStr)
fields = vars(obj)

lines = ioStr.split('\n')
for l in range(len(lines)): # TODO fix lines meaby?
assignments = lines[l].split('->')
varName = assignments[0].strip()
foundField = None

for field in fields:
if varName == field:
foundField = field
break

if foundField is None:
raise NameError(f"Object of type {objType} does not have field named {varName}.")

if isinstance(fields[foundField], primitive):
typeOfElement = type(fields[foundField])
val = _IoDes.read(assignments[1].strip(), typeOfElement)
setattr(obj, foundField, val) # TODO was 'field', why?
else:
# TODO add deserialization of classes and lists
pass
else:
raise NotImplementedError(f"Object of type {objType} is not supported.")
return obj

@staticmethod
def __substring_brackets(ioString):
firstIndex = -1
lastIndex = -1
for i in range(len(ioString)):
if ioString[i] == '|':
firstIndex = i + 1
break
for i in range(len(ioString)):
if ioString[len(ioString) - 1 - i] == '|':
lastIndex = len(ioString) - 1 - i
break
ioString = ioString[firstIndex:lastIndex]
return ioString

@staticmethod
def __delete_tabs(input_str):
ret = ""
lines = input_str.split('\n')
for i in range(len(lines)):
ret += (lines[i])[1:] + "\n"
return ret.strip()
41 changes: 41 additions & 0 deletions IoDeSer/_DeSer/_IoSer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import collections.abc
import inspect


class _IoSer:
@staticmethod
def __add_shift(shift) -> str:
ret = ""
for x in range(shift):
ret += "\t"
return ret

@staticmethod
def write(obj, shift_number) -> str:
primitive = (int, str, bool, float)
ret = ""
if isinstance(obj, primitive):
ret = "|" + str(obj) + "|"
elif isinstance(obj, collections.abc.Sequence):
arrayRet = ""
for i in range(len(obj)):
arrayRet += _IoSer.__add_shift(shift_number + 1) + _IoSer.write(obj[i], shift_number + 1)
if i < len(obj) - 1:
arrayRet += "\n" + _IoSer.__add_shift(shift_number + 1) + "+\n"
ret = "|\n" + arrayRet + "\n" + _IoSer.__add_shift(shift_number) + "|"
elif inspect.isclass(obj):
fields = vars(obj)
classRet = ""
first = True

for field in fields:
value = fields[field]
if not first:
classRet += "\n"
first = False
classRet += _IoSer.__add_shift(shift_number + 1) + field + "->" + _IoSer.write(value, shift_number + 1)
ret = "|\n" + classRet + "\n" + _IoSer.__add_shift(shift_number) + "|"
else:
raise NotImplementedError(f"Object of type {type(obj)} is not supported.")

return ret
122 changes: 12 additions & 110 deletions IoDeSer/io.py
Original file line number Diff line number Diff line change
@@ -1,120 +1,22 @@
import collections.abc
from typing import TextIO, Type

from IoDeSer._DeSer._IoDes import _IoDes
from IoDeSer._DeSer._IoSer import _IoSer


class IoFile:
@staticmethod
def write_to_file(obj, file):
file.write(IoFile().__write(obj, 0))
def write_to_file(obj: object, file: TextIO):
file.write(IoFile.write_to_string(obj))

@staticmethod
def write_to_string(obj) -> str:
return IoFile().__write(obj, 0)
def write_to_string(obj: object) -> str:
return _IoSer.write(obj, 0)

@staticmethod
def read_from_file(file, type):
return IoFile().__read(file.read(), type)
def read_from_file(file: TextIO, object_type: Type) -> object:
return IoFile.read_from_str(file.read(), object_type)

@staticmethod
def read_from_str(ioStr, type):
return IoFile().__read(ioStr, type)

def __add_shift(self, shift) -> str:
ret = ""
for x in range(shift):
ret += "\t"
return ret

def __write(self, obj, shift_number) -> str:
primitive = (int, str, bool, float)
ret = ""
if isinstance(obj, primitive):
ret = "|" + str(obj) + "|"
elif isinstance(obj, collections.abc.Sequence):
arrayRet = ""
for i in range(len(obj)):
arrayRet += self.__add_shift(shift_number + 1) + self.__write(obj[i], shift_number + 1)
if i < len(obj) - 1:
arrayRet += "\n" + self.__add_shift(shift_number + 1) + "+\n"
ret = "|\n" + arrayRet + "\n" + self.__add_shift(shift_number) + "|"
else: # inspect.isclass(obj):
fields = vars(obj)
classRet = ""
first = True

for field in fields:
value = fields[field]
if not first:
classRet += "\n"
first = False
classRet += self.__add_shift(shift_number + 1) + field + "->" + self.__write(value, shift_number + 1)
ret = "|\n" + classRet + "\n" + self.__add_shift(shift_number) + "|"
return ret

def __substring_brackets(self, ioString):
firstIndex = -1
lastIndex = -1
for i in range(len(ioString)):
if ioString[i] == '|':
firstIndex = i + 1
break
for i in range(len(ioString)):
if ioString[len(ioString) - 1 - i] == '|':
lastIndex = len(ioString) - 1 - i
break
ioString = ioString[firstIndex:lastIndex]
return ioString

def __delete_tabs(self, str):
ret = ""
lines = str.split('\n')
for i in range(len(lines)):
ret += (lines[i])[1:] + "\n"
return ret.strip()

def __read(self, ioStr, objType):
obj = ...
ioStr = self.__substring_brackets(ioStr)
primitive = (int, str, bool, float)
if objType in primitive:
obj = objType(ioStr)
elif objType == list:
ioStr = self.__delete_tabs(ioStr)
lst = []
lines = ioStr.split('\n+\n')
for i in range(len(lines)):
lst.append(self.__read(lines[i], str))
# TODO convert to proper element type, not 'str'
obj = lst
else:
try:
obj = objType()
except TypeError:
raise TypeError("Object of type "+str(objType)+" must have parameterless constructor or with default values.")
ioStr = self.__delete_tabs(ioStr)
fields = vars(obj)

lines = ioStr.split('\n')
for l in range(len(lines)):
assignments = lines[l].split('->')
varName = assignments[0].strip()
foundField=...

for field in fields:
if varName == field:
foundField = field
break


if foundField is None:
raise NameError("Object of type "+str(objType)+" does not have field named "+varName)

if isinstance(fields[foundField], primitive):
typeOfElement = type(fields[foundField])
val = self.__read(assignments[1].strip(), typeOfElement)
setattr(obj, field, val)
pass
else:
# TODO add deserialization of classes and lists
pass

return obj
def read_from_str(ioStr: str, object_type: Type) -> object:
return _IoDes.read(ioStr, object_type)
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
setup(
name='IoDeSer',
packages=find_packages(),
version='0.3.0',
version='0.3.1',
description='Python library for de/serialization of .io file format.',
author='IoDeSer',
author='Io-Maciek',
license='MIT'
)

0 comments on commit bbb771d

Please sign in to comment.