text: """
  复杂数据 + 数据多态 演示
  本次例子都来源于飞书开发平台，飞书拥有很强大的且灵活的api，所以配置的数据也相对复杂；
  """
  import typing
  from ex_dataclass import ex_dataclass, asdict, field, EXpack
  
  # ============================================= 示例一 =============================================
  
  # 这是一个飞书平台的富文本消息数据结构, 可以看到它最终发送的内容其实是一个多态内容是不确定性的，下面看看ex_dataclass的表现
  # https://open.feishu.cn/document/ukTMukTMukTM/uMDMxEjLzATMx4yMwETM
  complex_data = {
      "open_id" : "ou_5ad573a6411d72b8305fda3a9c15c70e",
      "chat_id" : "oc_5ad11d72b830411d72b836c20",
      "email"   : "fanlv@gmail.com",
      "msg_type": "post",
      "content" : {
          "post": {
              "en_us": {},
              "zh_cn": {
                  "title"  : "我是一个标题",
                  "content": [
                      [
                          {
                              # 第一种 tag
                              "tag"      : "text",
                              "un_escape": True,
                              "text"     : "第一行&nbsp;:"
                          },
                          {
                              # 第二种 tag
                              "tag" : "a",
                              "text": "超链接",
                              "href": "http://www.feishu.cn"
                          },
                          {
                              # 第三种 tag
                              "tag"    : "at",
                              "user_id": "ou_18eac85d35a26f989317ad4f02e8bbbb"
                          }
                      ],
                      [
                          {
                              "tag"      : "text",
                              "un_escape": False,
                              "text"     : "第二行 :"
                          },
                          {
                              "tag"      : "text",
                              "un_escape": False,
                              "text"     : "文本测试"
                          }
                      ],
                      [
                          {
                              # 第四种 tag
                              "tag"      : "img",
                              "image_key": "d640eeea-4d2f-4cb3-88d8-c964fab53987",
                              "width"    : 300,
                              "height"   : 300
                          }
                      ]
                  ]
              }
          }
      }
  }
  
  
  # 从上面的数据可以看到有4种不同tag的数据类型，但其实都是content, 下面看看怎么定义
  @ex_dataclass
  class TagBasic:
      tag: str = field(default_factory=str)
  
  
  # 第一种 tag: text
  @ex_dataclass
  class TagText(TagBasic):
      text: str = field(default_factory=str)
      un_escape: bool = field(default_factory=bool)
  
  
  # 第二种 tag: a
  @ex_dataclass
  class TagA(TagBasic):
      text: str = field(default_factory=str)
      href: str = field(default_factory=str)
  
  
  # 第三种 tag: at
  @ex_dataclass
  class TagAt(TagBasic):
      user_id: str = field(default_factory=str)
  
  
  # 第四种 tag: img
  @ex_dataclass
  class TagImg(TagBasic):
      image_key: str = field(default_factory=str)
      width: int = field(default_factory=int)
      height: int = field(default_factory=int)
  
  
  @ex_dataclass
  class PostContent:
      title: str = field(default_factory=str)
  
  
  # 英文内容没有所以为空
  @ex_dataclass
  class EnUsContent(PostContent):
      pass
  
  
  @ex_dataclass
  class ZhCnContent(PostContent):
      # 可以看到它其实是有两层列表嵌套
      # 这里有两种写法：
      # 1、typing.Type 的意思是主要标注父类其子类也会被进行匹配
      # 2、typing.Union 就是其中之一：typing.Union[], 优先级从左往右匹配
      content: typing.List[typing.List[typing.Type[TagBasic]]] = field(default_factory=list)
      # content: typing.List[typing.List[typing.Union[TagA, TagAt, TagImg, TagText]]] = field(default_factory=list)
  
  
  @ex_dataclass(ex_debug=False)
  class PostLangOption:
      # 如果默认值是想留空，给dict即可；否则给ZhCnContent
      zh_cn: ZhCnContent = field(default_factory=dict)
      en_us: EnUsContent = field(default_factory=dict, required=False)
  
  
  @ex_dataclass
  class MsgTypePost:
      post: PostLangOption = field(default_factory=PostLangOption)
  
  
  @ex_dataclass(ex_debug=False)
  class SendMessageReq(EXpack):
      email: str = field(default_factory=str)
      msg_type: str = field(default_factory=str)
      open_id: str = field(default_factory=str)
      chat_id: str = field(default_factory=str)
      content: MsgTypePost = field(default_factory=MsgTypePost)
  
  
  send_msg_req_1 = SendMessageReq(**complex_data)
  print(send_msg_req_1)
  # SendMessageReq(email='fanlv@gmail.com', msg_type='post', open_id='ou_5ad573a6411d72b8305fda3a9c15c70e', chat_id='oc_5ad11d72b830411d72b836c20', content=MsgTypePost(post=PostLangOption(zh_cn=ZhCnContent(title='我是一个标题', content=[[TagText(tag='text', text='第一行&nbsp;:', un_escape=True), TagA(tag='a', text='超链接', href='http://www.feishu.cn'), TagAt(tag='at', user_id='ou_18eac85d35a26f989317ad4f02e8bbbb')], [TagText(tag='text', text='第二行 :', un_escape=False), TagText(tag='text', text='文本测试', un_escape=False)], [TagImg(tag='img', image_key='d640eeea-4d2f-4cb3-88d8-c964fab53987', width=300, height=300)]]), en_us=EnUsContent(title=''))))
  assert type(send_msg_req_1.content) == MsgTypePost, True
  assert type(send_msg_req_1.content.post.zh_cn) == ZhCnContent, True
  assert type(send_msg_req_1.content.post.zh_cn.content[0][0]) == TagText, True
  assert type(send_msg_req_1.content.post.zh_cn.content[0][1]) == TagA, True
  assert type(send_msg_req_1.content.post.zh_cn.content[0][2]) == TagAt, True
  assert type(send_msg_req_1.content.post.zh_cn.content[2][0]) == TagImg, True
  send_msg_req_1.pprint()
  
  