refactor to allow custom serializer