Skip to content

Commit

Permalink
Added to_dict method to Message (fixes #107) (#108)
Browse files Browse the repository at this point in the history
* require ruamel

* added base module

* added from_dict and to_dict to Time

* bug fix: bad dep name

* added to_dict to Message

* added basic test_to_dict
  • Loading branch information
ChrisTimperley authored Mar 18, 2019
1 parent 0439492 commit b4277ca
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 9 deletions.
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
license='mit',
install_requires=[
'attrs>=17.2.0',
'typing-extensions>=3.7.2'
'typing-extensions>=3.7.2',
'ruamel.yaml>=0.15.89'
],
setup_requires=[
'pytest-runner'
Expand Down
2 changes: 1 addition & 1 deletion src/rozzy/definitions/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from .base import Time
from .msg import Constant, ConstantValue, Field, MsgFormat
from .srv import SrvFormat
from .action import ActionFormat
from .package import Package, PackageDatabase
from .bag import Time
from .format import FormatDatabase
from .type_db import TypeDatabase, Message
10 changes: 3 additions & 7 deletions src/rozzy/definitions/bag.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__all__ = ['BagReader']
__all__ = ('BagReader',)

from typing import (Dict, Sequence, Union, Optional, Tuple, List, Type,
Callable)
Expand All @@ -12,16 +12,12 @@

import attr

from .base import Time

logger: logging.Logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)


@attr.s(frozen=True, slots=True)
class Time:
secs: int = attr.ib()
nsecs: int = attr.ib()


def decode_uint8(v: bytes) -> int:
return struct.unpack('<B', v)[0]

Expand Down
19 changes: 19 additions & 0 deletions src/rozzy/definitions/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
__all__ = ('Time',)

from typing import Dict, Any

import attr


@attr.s(frozen=True, slots=True)
class Time:
secs: int = attr.ib()
nsecs: int = attr.ib()

@staticmethod
def from_dict(d: Dict[str, Any]) -> 'Time':
return Time(d['secs'], d['nsecs'])

def to_dict(self) -> Dict[str, int]:
return {'secs': self.secs,
'nsecs': self.nsecs}
28 changes: 28 additions & 0 deletions src/rozzy/definitions/type_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from .msg import MsgFormat
from .format import FormatDatabase
from .base import Time


class Message:
Expand All @@ -14,6 +15,33 @@ class Message:
"""
format: ClassVar[MsgFormat]

@staticmethod
def _to_dict_value(val: Any) -> Any:
typ = type(val)

if typ == Time or isinstance(typ, Message):
return val.to_dict()

if typ in (list, tuple):
if not typ:
return []
typ_item = type(typ[0])
if typ_item == Time or isinstance(typ_item, Message):
return [vv.to_dict() for vv in val]
# includes (str, int, float)
return list(val)

# includes (str, int, float)
return val

def to_dict(self) -> Dict[str, Any]:
d: Dict[str, Any] = {}
for field in self.format.fields:
name: str = field.name
val = getattr(self, field.name)
d[name] = self._to_dict_value(val)
return d


class TypeDatabase(Mapping[str, Type[Message]]):
@staticmethod
Expand Down
16 changes: 16 additions & 0 deletions test/test_type_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,19 @@ def test_build():
t(foo='bar')
with pytest.raises(TypeError):
t('foo', 'bar')


def test_to_dict():
s = """
uint32 seq
time stamp
string frame_id
"""
fmt = MsgFormat.from_string("PkgName", "MessageName", s)
t = TypeDatabase.build_type(fmt)

m = t(seq=310, stamp=Time(30, 120), frame_id='foo')
assert m.to_dict() == {
'seq': 310,
'stamp': {'secs': 30, 'nsecs': 120},
'frame_id': 'foo'}

0 comments on commit b4277ca

Please sign in to comment.