value-object-pattern 1.0.0__tar.gz → 1.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/PKG-INFO +1 -1
  2. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/__init__.py +1 -1
  3. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/decorators/value_object_validation.py +11 -1
  4. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/models/value_object.py +29 -3
  5. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/world/europe/spain/__init__.py +2 -2
  6. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/world/europe/spain/dni_value_object.py +41 -19
  7. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/world/europe/spain/nie_value_object.py +43 -22
  8. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/world/europe/spain/nif_value_object.py +48 -14
  9. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/world/europe/spain/nuss_value_object.py +29 -8
  10. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/world/europe/spain/passport_value_object.py +28 -6
  11. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/world/europe/spain/phone_number_value_object.py +38 -20
  12. value_object_pattern-1.2.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/__init__.py +51 -0
  13. value_object_pattern-1.0.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/administrative_technician_plate_value_object.py → value_object_pattern-1.2.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/administrative_technician_vehicle_plate_value_object.py +16 -16
  14. value_object_pattern-1.0.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/air_force_plate_value_object.py → value_object_pattern-1.2.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/air_force_vehicle_plate_value_object.py +16 -16
  15. value_object_pattern-1.0.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/army_plate_value_object.py → value_object_pattern-1.2.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/army_vehicle_plate_value_object.py +17 -17
  16. value_object_pattern-1.0.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/canarias_police_plate_value_object.py → value_object_pattern-1.2.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/canarias_police_vehicle_plate_value_object.py +16 -16
  17. value_object_pattern-1.0.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/catalan_police_plate_value_object.py → value_object_pattern-1.2.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/catalan_police_vehicle_plate_value_object.py +16 -16
  18. value_object_pattern-1.0.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/civil_guard_plate_value_object.py → value_object_pattern-1.2.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/civil_guard_vehicle_plate_value_object.py +18 -16
  19. value_object_pattern-1.0.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/consular_corps_plate_value_object.py → value_object_pattern-1.2.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/consular_corps_vehicle_plate_value_object.py +16 -16
  20. value_object_pattern-1.0.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/diplomatic_corps_plate_value_object.py → value_object_pattern-1.2.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/diplomatic_corps_vehicle_plate_value_object.py +16 -16
  21. value_object_pattern-1.0.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/especial_plate_value_object.py → value_object_pattern-1.2.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/especial_plate_vehicle_plate_value_object.py +16 -16
  22. value_object_pattern-1.0.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/historical_plate_value_object.py → value_object_pattern-1.2.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/historical_vehicle_plate_value_object.py +16 -16
  23. value_object_pattern-1.0.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/international_organization_plate_value_object.py → value_object_pattern-1.2.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/international_organization_vehicle_plate_value_object.py +16 -16
  24. value_object_pattern-1.0.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/ministry_development_plate_value_object.py → value_object_pattern-1.2.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/ministry_development_vehicle_plate_value_object.py +16 -16
  25. value_object_pattern-1.0.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/ministry_environment_plate_value_object.py → value_object_pattern-1.2.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/ministry_environment_vehicle_plate_value_object.py +16 -16
  26. value_object_pattern-1.0.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/national_police_plate_value_object.py → value_object_pattern-1.2.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/national_police_vehicle_plate_value_object.py +18 -16
  27. value_object_pattern-1.0.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/navy_plate_value_object.py → value_object_pattern-1.2.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/navy_vehicle_plate_value_object.py +17 -17
  28. value_object_pattern-1.0.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/ordinary_truck_plate_value_object.py → value_object_pattern-1.2.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/ordinary_truck_vehicle_plate_value_object.py +16 -16
  29. value_object_pattern-1.0.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/ordinary_plate_value_object.py → value_object_pattern-1.2.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/ordinary_vehicle_plate_value_object.py +16 -16
  30. value_object_pattern-1.0.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/provincial_system_plate_value_object.py → value_object_pattern-1.2.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/provincial_system_vehicle_plate_value_object.py +16 -16
  31. value_object_pattern-1.0.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/state_motor_pool_plate_value_object.py → value_object_pattern-1.2.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/state_motor_pool_vehicle_plate_value_object.py +16 -16
  32. value_object_pattern-1.0.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/temporal_company_not_registered_plate_value_object.py → value_object_pattern-1.2.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/temporal_company_not_registered_vehicle_plate_value_object.py +16 -16
  33. value_object_pattern-1.0.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/temporal_company_registered_plate_value_object.py → value_object_pattern-1.2.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/temporal_company_registered_vehicle_plate_value_object.py +16 -16
  34. value_object_pattern-1.0.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/temporal_private_individual_plate_value_object.py → value_object_pattern-1.2.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/temporal_private_individual_vehicle_plate_value_object.py +16 -16
  35. value_object_pattern-1.0.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/two_wheels_plate_value_object.py → value_object_pattern-1.2.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/two_wheels_vehicle_plate_value_object.py +16 -16
  36. value_object_pattern-1.2.0/value_object_pattern/usables/identifiers/world/europe/spain/vehicle_plate_value_object.py +131 -0
  37. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/world/vin_value_object.py +15 -5
  38. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/internet/__init__.py +12 -0
  39. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/internet/aws_cloud_region_value_object.py +3 -26
  40. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/internet/domain_value_object.py +13 -34
  41. value_object_pattern-1.2.0/value_object_pattern/usables/internet/mac_address_value_object.py +241 -0
  42. value_object_pattern-1.2.0/value_object_pattern/usables/internet/mac_addresses/__init__.py +13 -0
  43. value_object_pattern-1.2.0/value_object_pattern/usables/internet/mac_addresses/cisco_mac_address_value_object.py +175 -0
  44. value_object_pattern-1.2.0/value_object_pattern/usables/internet/mac_addresses/raw_mac_address_value_object.py +172 -0
  45. value_object_pattern-1.2.0/value_object_pattern/usables/internet/mac_addresses/space_mac_address_value_object.py +173 -0
  46. value_object_pattern-1.2.0/value_object_pattern/usables/internet/mac_addresses/universal_mac_address_value_object.py +173 -0
  47. value_object_pattern-1.2.0/value_object_pattern/usables/internet/mac_addresses/windows_mac_address_value_object.py +173 -0
  48. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/internet/mobile/imei_value_object.py +27 -7
  49. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/internet/port_value_object.py +4 -4
  50. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/internet/uri/url_value_object.py +10 -10
  51. value_object_pattern-1.2.0/value_object_pattern/usables/internet/utils/__init__.py +43 -0
  52. value_object_pattern-1.2.0/value_object_pattern/usables/internet/utils/aws_regions.txt +34 -0
  53. value_object_pattern-1.2.0/value_object_pattern/usables/internet/utils/tld_domains.txt +1445 -0
  54. value_object_pattern-1.2.0/value_object_pattern/usables/money/__init__.py +7 -0
  55. value_object_pattern-1.2.0/value_object_pattern/usables/money/credit_card_value_object.py +90 -0
  56. value_object_pattern-1.2.0/value_object_pattern/usables/money/credit_cards/__init__.py +11 -0
  57. value_object_pattern-1.2.0/value_object_pattern/usables/money/credit_cards/amex_credit_card_value_object.py +92 -0
  58. value_object_pattern-1.2.0/value_object_pattern/usables/money/credit_cards/discover_credit_card_value_object.py +92 -0
  59. value_object_pattern-1.2.0/value_object_pattern/usables/money/credit_cards/mastercard_credit_card_value_object.py +92 -0
  60. value_object_pattern-1.2.0/value_object_pattern/usables/money/credit_cards/visa_credit_card_value_object.py +92 -0
  61. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/money/iban_value_object.py +41 -50
  62. value_object_pattern-1.2.0/value_object_pattern/usables/utils/__init__.py +3 -0
  63. value_object_pattern-1.2.0/value_object_pattern/usables/utils/luhn_validation.py +25 -0
  64. value_object_pattern-1.0.0/value_object_pattern/usables/identifiers/world/europe/spain/car_plate_value_object.py +0 -142
  65. value_object_pattern-1.0.0/value_object_pattern/usables/identifiers/world/europe/spain/plates/__init__.py +0 -49
  66. value_object_pattern-1.0.0/value_object_pattern/usables/internet/mac_address_value_object.py +0 -390
  67. value_object_pattern-1.0.0/value_object_pattern/usables/money/__init__.py +0 -3
  68. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/.gitignore +0 -0
  69. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/LICENSE.md +0 -0
  70. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/README.md +0 -0
  71. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/pyproject.toml +0 -0
  72. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/decorators/__init__.py +0 -0
  73. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/decorators/value_object_process.py +0 -0
  74. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/models/__init__.py +0 -0
  75. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/models/base_model.py +0 -0
  76. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/models/collections/__init__.py +0 -0
  77. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/models/collections/list_value_object.py +0 -0
  78. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/models/enumeration_value_object.py +0 -0
  79. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/py.typed +0 -0
  80. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/__init__.py +0 -0
  81. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/dates/__init__.py +0 -0
  82. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/dates/date/__init__.py +0 -0
  83. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/dates/date/date_value_object.py +0 -0
  84. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/dates/date/string_date_value_object.py +0 -0
  85. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/dates/datetime/__init__.py +0 -0
  86. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/dates/datetime/datetime_value_object.py +0 -0
  87. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/dates/datetime/string_datetime_value_object.py +0 -0
  88. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/dates/timezone/__init__.py +0 -0
  89. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/dates/timezone/string_timezone_value_object.py +0 -0
  90. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/dates/timezone/timezone_value_object.py +0 -0
  91. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/__init__.py +0 -0
  92. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/uuid/__init__.py +0 -0
  93. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/uuid/string_uuid_v4_value_object.py +0 -0
  94. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/uuid/string_uuid_value_object.py +0 -0
  95. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/uuid/uuid_v4_value_object.py +0 -0
  96. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/uuid/uuid_value_object.py +0 -0
  97. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/world/__init__.py +0 -0
  98. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/world/country_tld_value_object.py +0 -0
  99. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/world/europe/__init__.py +0 -0
  100. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/world/europe/spain/plates/utils/__init__.py +0 -0
  101. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/world/europe/spain/plates/utils/provincial_plate_codes.txt +0 -0
  102. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/world/iso3166_alpha2_code_value_object.py +0 -0
  103. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/world/iso3166_alpha3_code_value_object.py +0 -0
  104. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/world/iso3166_numeric_code_value_object.py +0 -0
  105. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/world/phone_code_value_object.py +0 -0
  106. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/world/utils/__init__.py +0 -0
  107. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/world/utils/iso3166_alpha2_codes.txt +0 -0
  108. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/world/utils/iso3166_alpha2_to_alpha3_mapping.txt +0 -0
  109. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/world/utils/iso3166_alpha2_to_numeric_mapping.txt +0 -0
  110. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/world/utils/iso3166_alpha2_to_phone_code_mapping.txt +0 -0
  111. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/world/utils/iso3166_alpha2_to_tld_mapping.txt +0 -0
  112. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/world/utils/iso3166_alpha3_codes.txt +0 -0
  113. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/identifiers/world/utils/iso3166_numeric_codes.txt +0 -0
  114. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/internet/host_value_object.py +0 -0
  115. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/internet/ipv4_address_value_object.py +0 -0
  116. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/internet/ipv4_network_value_object.py +0 -0
  117. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/internet/ipv6_address_value_object.py +0 -0
  118. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/internet/ipv6_network_value_object.py +0 -0
  119. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/internet/mobile/__init__.py +0 -0
  120. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/internet/uri/__init__.py +0 -0
  121. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/internet/uri/http_https_url_value_object.py +0 -0
  122. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/internet/uri/http_url_value_object.py +0 -0
  123. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/internet/uri/https_url_value_object.py +0 -0
  124. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/money/utils/__init__.py +0 -0
  125. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/money/utils/iban_lengths.txt +0 -0
  126. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/__init__.py +0 -0
  127. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/boolean/__init__.py +0 -0
  128. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/boolean/boolean_value_object.py +0 -0
  129. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/boolean/false_value_object.py +0 -0
  130. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/boolean/true_value_object.py +0 -0
  131. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/bytes/__init__.py +0 -0
  132. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/bytes/bytes_value_object.py +0 -0
  133. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/float/__init__.py +0 -0
  134. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/float/float_value_object.py +0 -0
  135. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/float/negative_float_value_object.py +0 -0
  136. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/float/positive_float_value_object.py +0 -0
  137. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/integer/__init__.py +0 -0
  138. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/integer/even_integer_value_object.py +0 -0
  139. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/integer/integer_value_object.py +0 -0
  140. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/integer/negative_integer_value_object.py +0 -0
  141. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/integer/odd_integer_value_object.py +0 -0
  142. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/integer/positive_integer_value_object.py +0 -0
  143. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/none/__init__.py +0 -0
  144. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/none/none_value_object.py +0 -0
  145. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/none/not_none_value_object.py +0 -0
  146. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/string/__init__.py +0 -0
  147. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/string/alpha_value_object.py +0 -0
  148. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/string/alphanumeric_value_object.py +0 -0
  149. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/string/digit_value_object.py +0 -0
  150. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/string/lowercase_string_value_object.py +0 -0
  151. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/string/non_empty_string_value_object.py +0 -0
  152. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/string/printable_string_value_object.py +0 -0
  153. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/string/string_value_object.py +0 -0
  154. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/string/trimmed_string_value_object.py +0 -0
  155. {value_object_pattern-1.0.0 → value_object_pattern-1.2.0}/value_object_pattern/usables/primitives/string/uppercase_string_value_object.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: value-object-pattern
3
- Version: 1.0.0
3
+ Version: 1.2.0
4
4
  Summary: The Value Object Pattern is a Python package that streamlines the creation and management of value objects in your projects.
5
5
  Project-URL: Homepage, https://github.com/adriamontoto/value-object-pattern
6
6
  Project-URL: Repository, https://github.com/adriamontoto/value-object-pattern
@@ -1,4 +1,4 @@
1
- __version__ = '1.0.0'
1
+ __version__ = '1.2.0'
2
2
 
3
3
  from .decorators import process, validation
4
4
  from .models import BaseModel, EnumerationValueObject, ValueObject
@@ -6,17 +6,22 @@ from functools import wraps
6
6
  from typing import Any, Callable
7
7
 
8
8
 
9
- def validation(order: int | None = None) -> Callable[[Callable[..., None]], Callable[..., None]]:
9
+ def validation(
10
+ order: int | None = None,
11
+ early_process: bool = False,
12
+ ) -> Callable[[Callable[..., None]], Callable[..., None]]:
10
13
  """
11
14
  Decorator for validation the value before the value is created.
12
15
 
13
16
  Args:
14
17
  order (int | None, optional): The order of the validation that will be executed, if None the functions will be
15
18
  executed alphabetically. Defaults to None.
19
+ early_process (bool, optional): If True, the value will be processed before the validation. Defaults to False.
16
20
 
17
21
  Raises:
18
22
  TypeError: If the order is not an integer.
19
23
  ValueError: If the order is not equal or greater than 0.
24
+ TypeError: If early_process is not a boolean.
20
25
 
21
26
  Returns:
22
27
  Callable[[Callable[..., None]], Callable[..., None]]: Wrapper function for the validation.
@@ -48,6 +53,7 @@ def validation(order: int | None = None) -> Callable[[Callable[..., None]], Call
48
53
  Raises:
49
54
  TypeError: If the order is not an integer.
50
55
  ValueError: If the order is not equal or greater than 0.
56
+ TypeError: If early_process is not a boolean.
51
57
 
52
58
  Returns:
53
59
  Callable[..., None]: Wrapper function for the validation.
@@ -59,8 +65,12 @@ def validation(order: int | None = None) -> Callable[[Callable[..., None]], Call
59
65
  if order < 0:
60
66
  raise ValueError(f'Validation order <<<{order}>>> must be equal or greater than 0.')
61
67
 
68
+ if type(early_process) is not bool:
69
+ raise TypeError(f'Validation early_process <<<{early_process}>>> must be a boolean. Got <<<{type(early_process).__name__}>>> type.') # noqa: E501 # fmt: skip
70
+
62
71
  function._is_validation = True # type: ignore[attr-defined]
63
72
  function._order = function.__name__ if order is None else str(order) # type: ignore[attr-defined]
73
+ function._early_process = early_process # type: ignore[attr-defined]
64
74
 
65
75
  @wraps(wrapped=function)
66
76
  def wrapper(*args: tuple[Any, ...], **kwargs: dict[str, Any]) -> None:
@@ -37,12 +37,13 @@ class ValueObject(ABC, Generic[T]): # noqa: UP046
37
37
  ```
38
38
  """
39
39
 
40
- __slots__ = ('_parameter', '_title', '_value')
41
- __match_args__ = ('_parameter', '_title', '_value')
40
+ __slots__ = ('_early_processed', '_parameter', '_title', '_value')
41
+ __match_args__ = ('_early_processed', '_parameter', '_title', '_value')
42
42
 
43
43
  _value: T
44
44
  _title: str
45
45
  _parameter: str
46
+ _early_processed: T | None
46
47
 
47
48
  def __init__(self, *, value: T, title: str | None = None, parameter: str | None = None) -> None:
48
49
  """
@@ -103,9 +104,10 @@ class ValueObject(ABC, Generic[T]): # noqa: UP046
103
104
 
104
105
  object.__setattr__(self, '_title', title)
105
106
  object.__setattr__(self, '_parameter', parameter)
107
+ object.__setattr__(self, '_early_processed', None)
106
108
 
107
109
  self._validate(value=value)
108
- value = self._process(value=value)
110
+ value = self._process(value=value) if self._early_processed is None else self._early_processed
109
111
 
110
112
  object.__setattr__(self, '_value', value)
111
113
 
@@ -266,6 +268,10 @@ class ValueObject(ABC, Generic[T]): # noqa: UP046
266
268
  methods = self._gather_decorated_methods(instance=self, attribute_name='_is_validation')
267
269
  while methods:
268
270
  method: Callable[..., T] = methods.popleft().__get__(self, self.__class__)
271
+ if getattr(method, '_early_process', False):
272
+ method(value=self.early_process(value=value))
273
+ continue
274
+
269
275
  method(value=value)
270
276
 
271
277
  except Exception as error:
@@ -362,6 +368,26 @@ class ValueObject(ABC, Generic[T]): # noqa: UP046
362
368
  # sort by class hierarchy, method order attribute, and method name
363
369
  return deque([method for _, _, method in sorted(classes_methods, key=sort_key)])
364
370
 
371
+ def early_process(self, value: T) -> T:
372
+ """
373
+ This method processes the value object value before validation. This is useful for early processing of the value
374
+ object value where you need to have a format before validating. If the value object has already been early
375
+ processed, it returns the already processed value.
376
+
377
+ Args:
378
+ value (T): The value object value.
379
+
380
+ Returns:
381
+ T: The processed value object value.
382
+ """
383
+ if self._early_processed is not None:
384
+ return self._early_processed
385
+
386
+ processed_value = self._process(value=value)
387
+ object.__setattr__(self, '_early_processed', processed_value)
388
+
389
+ return processed_value
390
+
365
391
  @property
366
392
  def value(self) -> T:
367
393
  """
@@ -1,17 +1,17 @@
1
- from .car_plate_value_object import CarPlateValueObject
2
1
  from .dni_value_object import DniValueObject
3
2
  from .nie_value_object import NieValueObject
4
3
  from .nif_value_object import NifValueObject
5
4
  from .nuss_value_object import NussValueObject
6
5
  from .passport_value_object import PassportValueObject
7
6
  from .phone_number_value_object import PhoneNumberValueObject
7
+ from .vehicle_plate_value_object import VehiclePlateValueObject
8
8
 
9
9
  __all__ = (
10
- 'CarPlateValueObject',
11
10
  'DniValueObject',
12
11
  'NieValueObject',
13
12
  'NifValueObject',
14
13
  'NussValueObject',
15
14
  'PassportValueObject',
16
15
  'PhoneNumberValueObject',
16
+ 'VehiclePlateValueObject',
17
17
  )
@@ -26,8 +26,8 @@ class DniValueObject(NotEmptyStringValueObject, TrimmedStringValueObject):
26
26
  ```
27
27
  """
28
28
 
29
- __DNI_VALUE_OBJECT_LETTERS: str = 'TRWAGMYFPDXBNJZSQVHLCKE'
30
- __DNI_VALUE_OBJECT_REGEX: Pattern[str] = re_compile(pattern=r'([0-9]{8})([trwagmyfpdxbnjzsqvhlckeTRWAGMYFPDXBNJZSQVHLCKE])') # noqa: E501 # fmt: skip
29
+ _DNI_LETTERS: str = 'TRWAGMYFPDXBNJZSQVHLCKE'
30
+ _IDENTIFICATION_REGEX: Pattern[str] = re_compile(pattern=r'([0-9]{8})[-\s]?([trwagmyfpdxbnjzsqvhlckeTRWAGMYFPDXBNJZSQVHLCKE])') # noqa: E501 # fmt: skip
31
31
 
32
32
  @process(order=0)
33
33
  def _ensure_value_is_upper(self, value: str) -> str:
@@ -42,38 +42,50 @@ class DniValueObject(NotEmptyStringValueObject, TrimmedStringValueObject):
42
42
  """
43
43
  return value.upper()
44
44
 
45
- @validation(order=0)
46
- def _ensure_value_is_dni(self, value: str) -> None:
45
+ @process(order=1)
46
+ def _ensure_value_is_formatted(self, value: str) -> str:
47
47
  """
48
- Ensures the value object `value` is a Spanish DNI.
48
+ Ensures the value object `value` is stored without separators.
49
49
 
50
50
  Args:
51
51
  value (str): The provided value.
52
52
 
53
- Raises:
54
- ValueError: If the `value` is not a Spanish DNI.
53
+ Returns:
54
+ str: Formatted value.
55
55
  """
56
- match = self.__DNI_VALUE_OBJECT_REGEX.fullmatch(string=value)
57
- if not match:
58
- self._raise_value_is_not_dni(value=value)
56
+ return self._IDENTIFICATION_REGEX.sub(repl=r'\1\2', string=value)
59
57
 
60
- number, control_letter = match.groups()
58
+ @validation(order=0)
59
+ def _ensure_value_follows_identification_regex(self, value: str) -> None:
60
+ """
61
+ Ensures the value object `value` follows the identification regex.
61
62
 
62
- expected_letter = self._calculate_control_value(number=number)
63
- if control_letter.upper() != expected_letter:
63
+ Args:
64
+ value (str): The provided value.
65
+
66
+ Raises:
67
+ ValueError: If the `value` does not follow the identification regex.
68
+ """
69
+ if not self._IDENTIFICATION_REGEX.fullmatch(string=value):
64
70
  self._raise_value_is_not_dni(value=value)
65
71
 
66
- def _calculate_control_value(self, number: str) -> str:
72
+ @validation(order=1, early_process=True)
73
+ def _ensure_value_has_valid_control_letter(self, value: str) -> None:
67
74
  """
68
- Calculates the control letter for a given number in a Spanish DNI.
75
+ Ensures the value object `value` has a valid control letter.
69
76
 
70
77
  Args:
71
- number (str): The 8-digit number part of the DNI.
78
+ value (str): The provided value.
72
79
 
73
- Returns:
74
- str: The calculated control letter.
80
+ Raises:
81
+ ValueError: If the `value` does not have a valid control letter.
75
82
  """
76
- return self.__DNI_VALUE_OBJECT_LETTERS[int(number) % 23]
83
+ match = self._IDENTIFICATION_REGEX.fullmatch(string=value)
84
+ number, control_letter = match.groups() # type: ignore[union-attr]
85
+
86
+ expected_letter = self._DNI_LETTERS[int(number) % 23]
87
+ if control_letter != expected_letter:
88
+ self._raise_value_is_not_dni(value=value)
77
89
 
78
90
  def _raise_value_is_not_dni(self, value: str) -> NoReturn:
79
91
  """
@@ -86,3 +98,13 @@ class DniValueObject(NotEmptyStringValueObject, TrimmedStringValueObject):
86
98
  ValueError: If the `value` is not a Spanish DNI.
87
99
  """
88
100
  raise ValueError(f'DniValueObject value <<<{value}>>> is not a valid Spanish DNI.')
101
+
102
+ @classmethod
103
+ def regex(cls) -> Pattern[str]:
104
+ """
105
+ Returns a list of regex patterns used for validation.
106
+
107
+ Returns:
108
+ Pattern[str]: List of regex patterns.
109
+ """
110
+ return cls._IDENTIFICATION_REGEX
@@ -27,9 +27,9 @@ class NieValueObject(NotEmptyStringValueObject, TrimmedStringValueObject):
27
27
  ```
28
28
  """
29
29
 
30
- __NIE_VALUE_OBJECT_LETTERS: str = 'TRWAGMYFPDXBNJZSQVHLCKE'
31
- __NIE_VALUE_OBJECT_REGEX: Pattern[str] = re_compile(pattern=r'([xyzXYZ])([0-9]{7})([trwagmyfpdxbnjzsqvhlckeTRWAGMYFPDXBNJZSQVHLCKE])') # noqa: E501 # fmt: skip
32
- __NIE_VALUE_OBJECT_LETTER_TO_NUMBER: ClassVar[dict[str, str]] = {'X': '0', 'Y': '1', 'Z': '2'}
30
+ _NIE_LETTERS: str = 'TRWAGMYFPDXBNJZSQVHLCKE'
31
+ _NIE_LETTER_TO_NUMBER: ClassVar[dict[str, str]] = {'X': '0', 'Y': '1', 'Z': '2'}
32
+ _IDENTIFICATION_REGEX: Pattern[str] = re_compile(pattern=r'([xyzXYZ])[-\s]?([0-9]{7})[-\s]?([trwagmyfpdxbnjzsqvhlckeTRWAGMYFPDXBNJZSQVHLCKE])') # noqa: E501 # fmt: skip
33
33
 
34
34
  @process(order=0)
35
35
  def _ensure_value_is_upper(self, value: str) -> str:
@@ -44,40 +44,51 @@ class NieValueObject(NotEmptyStringValueObject, TrimmedStringValueObject):
44
44
  """
45
45
  return value.upper()
46
46
 
47
- @validation(order=0)
48
- def _ensure_value_is_nie(self, value: str) -> None:
47
+ @process(order=1)
48
+ def _ensure_value_is_formatted(self, value: str) -> str:
49
49
  """
50
- Ensures the value object `value` is a Spanish NIE.
50
+ Ensures the value object `value` is stored without separators.
51
51
 
52
52
  Args:
53
53
  value (str): The provided value.
54
54
 
55
- Raises:
56
- ValueError: If the `value` is not a Spanish NIE.
55
+ Returns:
56
+ str: Formatted value.
57
57
  """
58
- match = self.__NIE_VALUE_OBJECT_REGEX.fullmatch(string=value)
59
- if not match:
60
- self._raise_value_is_not_nie(value=value)
58
+ return self._IDENTIFICATION_REGEX.sub(repl=r'\1\2\3', string=value)
59
+
60
+ @validation(order=0)
61
+ def _ensure_value_follows_identification_regex(self, value: str) -> None:
62
+ """
63
+ Ensures the value object `value` follows the identification regex.
61
64
 
62
- first_letter, number, control_letter = match.groups()
65
+ Args:
66
+ value (str): The provided value.
63
67
 
64
- expected_letter = self._calculate_control_value(first_letter=first_letter, number=number)
65
- if control_letter.upper() != expected_letter:
68
+ Raises:
69
+ ValueError: If the `value` does not follow the identification regex.
70
+ """
71
+ if not self._IDENTIFICATION_REGEX.fullmatch(string=value):
66
72
  self._raise_value_is_not_nie(value=value)
67
73
 
68
- def _calculate_control_value(self, first_letter: str, number: str) -> str:
74
+ @validation(order=1, early_process=True)
75
+ def _ensure_value_has_valid_control_letter(self, value: str) -> None:
69
76
  """
70
- Calculates the control letter for a given NIE.
77
+ Ensures the value object `value` has a valid control letter.
71
78
 
72
79
  Args:
73
- first_letter (str): The first letter of the NIE (X, Y, or Z).
74
- number (str): The 7-digit number part of the NIE.
80
+ value (str): The provided value.
75
81
 
76
- Returns:
77
- str: The expected control letter.
82
+ Raises:
83
+ ValueError: If the `value` does not have a valid control letter.
78
84
  """
79
- number_for_calculation = self.__NIE_VALUE_OBJECT_LETTER_TO_NUMBER[first_letter] + number
80
- return self.__NIE_VALUE_OBJECT_LETTERS[int(number_for_calculation) % 23]
85
+ match = self._IDENTIFICATION_REGEX.fullmatch(string=value)
86
+ first_letter, number, control_letter = match.groups() # type: ignore[union-attr]
87
+
88
+ number_for_calculation = self._NIE_LETTER_TO_NUMBER[first_letter] + number
89
+ expected_letter = self._NIE_LETTERS[int(number_for_calculation) % 23]
90
+ if control_letter.upper() != expected_letter:
91
+ self._raise_value_is_not_nie(value=value)
81
92
 
82
93
  def _raise_value_is_not_nie(self, value: str) -> NoReturn:
83
94
  """
@@ -90,3 +101,13 @@ class NieValueObject(NotEmptyStringValueObject, TrimmedStringValueObject):
90
101
  ValueError: If the `value` is not a Spanish NIE.
91
102
  """
92
103
  raise ValueError(f'NieValueObject value <<<{value}>>> is not a valid Spanish NIE.')
104
+
105
+ @classmethod
106
+ def regex(cls) -> Pattern[str]:
107
+ """
108
+ Returns a list of regex patterns used for validation.
109
+
110
+ Returns:
111
+ Pattern[str]: List of regex patterns.
112
+ """
113
+ return cls._IDENTIFICATION_REGEX
@@ -27,10 +27,10 @@ class NifValueObject(NotEmptyStringValueObject, TrimmedStringValueObject):
27
27
  ```
28
28
  """
29
29
 
30
- __NIF_VALUE_OBJECT_REGEX: Pattern[str] = re_compile(pattern=r'([abcdefghjnpqrsuvwABCDEFGHJNPQRSUVW])([0-9]{7})([0-9abcdefghijABCDEFGHIJ])') # noqa: E501 # fmt: skip
31
- __NIF_VALUE_OBJECT_LETTER_CONTROL_LETTERS: ClassVar[list[str]] = ['J', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']
32
- __NIF_VALUE_OBJECT_CONTROL_CHARACTER_LETTERS: ClassVar[set[str]] = {'K', 'P', 'Q', 'S'}
33
- __NIF_VALUE_OBJECT_CONTROL_CHARACTER_DIGITS: ClassVar[set[str]] = {'A', 'B', 'E', 'H'}
30
+ _NIF_LETTER_CONTROL_LETTERS: ClassVar[list[str]] = ['J', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']
31
+ _NIF_CONTROL_CHARACTER_LETTERS: ClassVar[set[str]] = {'K', 'P', 'Q', 'S'}
32
+ _NIF_CONTROL_CHARACTER_DIGITS: ClassVar[set[str]] = {'A', 'B', 'E', 'H'}
33
+ _IDENTIFICATION_REGEX: Pattern[str] = re_compile(pattern=r'([abcdefghjnpqrsuvwABCDEFGHJNPQRSUVW])[-\s]?([0-9]{7})[-\s]?([0-9abcdefghijABCDEFGHIJ])') # noqa: E501 # fmt: skip
34
34
 
35
35
  @process(order=0)
36
36
  def _ensure_value_is_upper(self, value: str) -> str:
@@ -45,28 +45,52 @@ class NifValueObject(NotEmptyStringValueObject, TrimmedStringValueObject):
45
45
  """
46
46
  return value.upper()
47
47
 
48
+ @process(order=1)
49
+ def _ensure_value_is_formatted(self, value: str) -> str:
50
+ """
51
+ Ensures the value object `value` is stored without separators.
52
+
53
+ Args:
54
+ value (str): The provided value.
55
+
56
+ Returns:
57
+ str: Formatted value.
58
+ """
59
+ return self._IDENTIFICATION_REGEX.sub(repl=r'\1\2\3', string=value)
60
+
48
61
  @validation(order=0)
49
- def _ensure_value_is_nif(self, value: str) -> None:
62
+ def _ensure_value_follows_identification_regex(self, value: str) -> None:
50
63
  """
51
- Ensures the value object `value` is a Spanish company NIF.
64
+ Ensures the value object `value` follows the identification regex.
52
65
 
53
66
  Args:
54
67
  value (str): The provided value.
55
68
 
56
69
  Raises:
57
- ValueError: If the `value` is not a Spanish company NIF.
70
+ ValueError: If the `value` does not follow the identification regex.
58
71
  """
59
- match = self.__NIF_VALUE_OBJECT_REGEX.fullmatch(string=value)
60
- if not match:
72
+ if not self._IDENTIFICATION_REGEX.fullmatch(string=value):
61
73
  self._raise_value_is_not_nif(value=value)
62
74
 
63
- first_letter, number, control_character = match.groups()
75
+ @validation(order=1, early_process=True)
76
+ def _ensure_value_has_valid_control_letter(self, value: str) -> None:
77
+ """
78
+ Ensures the value object `value` has a valid control letter.
79
+
80
+ Args:
81
+ value (str): The provided value.
82
+
83
+ Raises:
84
+ ValueError: If the `value` does not have a valid control letter.
85
+ """
86
+ match = self._IDENTIFICATION_REGEX.fullmatch(string=value)
87
+ first_letter, number, control_character = match.groups() # type: ignore[union-attr]
64
88
 
65
89
  expected_number, expected_letter = self._calculate_control_values(number=number)
66
- if first_letter.upper() in self.__NIF_VALUE_OBJECT_CONTROL_CHARACTER_DIGITS:
90
+ if first_letter.upper() in self._NIF_CONTROL_CHARACTER_DIGITS:
67
91
  expected = {expected_number}
68
92
 
69
- elif first_letter.upper() in self.__NIF_VALUE_OBJECT_CONTROL_CHARACTER_LETTERS:
93
+ elif first_letter.upper() in self._NIF_CONTROL_CHARACTER_LETTERS:
70
94
  expected = {expected_letter}
71
95
 
72
96
  else:
@@ -86,7 +110,7 @@ class NifValueObject(NotEmptyStringValueObject, TrimmedStringValueObject):
86
110
  tuple[str, str]: The calculated control digit and letter.
87
111
  """
88
112
  total = 0
89
- for idx, digit in enumerate(number):
113
+ for idx, digit in enumerate(iterable=number):
90
114
  n = int(digit)
91
115
  if idx % 2 == 0:
92
116
  n *= 2
@@ -97,7 +121,7 @@ class NifValueObject(NotEmptyStringValueObject, TrimmedStringValueObject):
97
121
 
98
122
  control_value = (10 - (total % 10)) % 10
99
123
 
100
- return str(control_value), self.__NIF_VALUE_OBJECT_LETTER_CONTROL_LETTERS[control_value]
124
+ return str(control_value), self._NIF_LETTER_CONTROL_LETTERS[control_value]
101
125
 
102
126
  def _raise_value_is_not_nif(self, value: str) -> NoReturn:
103
127
  """
@@ -110,3 +134,13 @@ class NifValueObject(NotEmptyStringValueObject, TrimmedStringValueObject):
110
134
  ValueError: If the `value` is not a Spanish company NIF.
111
135
  """
112
136
  raise ValueError(f'NifValueObject value <<<{value}>>> is not a valid Spanish company NIF.')
137
+
138
+ @classmethod
139
+ def regex(cls) -> Pattern[str]:
140
+ """
141
+ Returns a list of regex patterns used for validation.
142
+
143
+ Returns:
144
+ Pattern[str]: List of regex patterns.
145
+ """
146
+ return cls._IDENTIFICATION_REGEX
@@ -26,7 +26,7 @@ class NussValueObject(NotEmptyStringValueObject, TrimmedStringValueObject):
26
26
  ```
27
27
  """
28
28
 
29
- __SOCIAL_SECURITY_NUMBER_VALUE_OBJECT_REGEX: Pattern[str] = re_compile(pattern=r'([0-9]{2})[-\s/]?([0-9]{7,8})[-\s/]?([0-9]{2})') # noqa: E501 # fmt: skip
29
+ _IDENTIFICATION_REGEX: Pattern[str] = re_compile(pattern=r'([0-9]{2})[-\s/]?([0-9]{7,8})[-\s/]?([0-9]{2})') # noqa: E501 # fmt: skip
30
30
 
31
31
  @process(order=0)
32
32
  def _ensure_value_is_formatted(self, value: str) -> str:
@@ -39,24 +39,35 @@ class NussValueObject(NotEmptyStringValueObject, TrimmedStringValueObject):
39
39
  Returns:
40
40
  str: Formatted value.
41
41
  """
42
- return self.__SOCIAL_SECURITY_NUMBER_VALUE_OBJECT_REGEX.sub(repl=r'\1\2\3', string=value)
42
+ return self._IDENTIFICATION_REGEX.sub(repl=r'\1\2\3', string=value)
43
43
 
44
44
  @validation(order=0)
45
- def _ensure_value_is_social_security_number(self, value: str) -> None:
45
+ def _ensure_value_follows_identification_regex(self, value: str) -> None:
46
46
  """
47
- Ensures the value object `value` is a valid Spanish Social Security Number.
47
+ Ensures the value object `value` follows the identification regex.
48
48
 
49
49
  Args:
50
50
  value (str): The provided value.
51
51
 
52
52
  Raises:
53
- ValueError: If the `value` is not a valid Spanish Social Security Number.
53
+ ValueError: If the `value` does not follow the identification regex.
54
54
  """
55
- match = self.__SOCIAL_SECURITY_NUMBER_VALUE_OBJECT_REGEX.fullmatch(string=value)
56
- if not match:
55
+ if not self._IDENTIFICATION_REGEX.fullmatch(string=value):
57
56
  self._raise_value_is_not_social_security_number(value=value)
58
57
 
59
- province, sequential, control = match.groups()
58
+ @validation(order=1, early_process=True)
59
+ def _ensure_value_has_valid_control_letter(self, value: str) -> None:
60
+ """
61
+ Ensures the value object `value` has a valid control letter.
62
+
63
+ Args:
64
+ value (str): The provided value.
65
+
66
+ Raises:
67
+ ValueError: If the `value` does not have a valid control letter.
68
+ """
69
+ match = self._IDENTIFICATION_REGEX.fullmatch(string=value)
70
+ province, sequential, control = match.groups() # type: ignore[union-attr]
60
71
 
61
72
  expected = self._calculate_control_value(province=province, sequential=sequential)
62
73
  if expected != int(control):
@@ -89,3 +100,13 @@ class NussValueObject(NotEmptyStringValueObject, TrimmedStringValueObject):
89
100
  ValueError: If the `value` is not a valid Spanish Social Security Number.
90
101
  """
91
102
  raise ValueError(f'NussValueObject value <<<{value}>>> is not a valid Spanish Social Security Number.') # noqa: E501 # fmt: skip
103
+
104
+ @classmethod
105
+ def regex(cls) -> Pattern[str]:
106
+ """
107
+ Returns a list of regex patterns used for validation.
108
+
109
+ Returns:
110
+ Pattern[str]: List of regex patterns.
111
+ """
112
+ return cls._IDENTIFICATION_REGEX
@@ -26,7 +26,7 @@ class PassportValueObject(NotEmptyStringValueObject, TrimmedStringValueObject):
26
26
  ```
27
27
  """
28
28
 
29
- __PASSPORT_VALUE_OBJECT_REGEX: Pattern[str] = re_compile(pattern=r'([a-zA-Z]{2,3})([0-9]{6})')
29
+ _IDENTIFICATION_REGEX: Pattern[str] = re_compile(pattern=r'([a-zA-Z]{2,3})[-\s]?([0-9]{6})')
30
30
 
31
31
  @process(order=0)
32
32
  def _ensure_value_is_upper(self, value: str) -> str:
@@ -41,19 +41,31 @@ class PassportValueObject(NotEmptyStringValueObject, TrimmedStringValueObject):
41
41
  """
42
42
  return value.upper()
43
43
 
44
+ @process(order=1)
45
+ def _ensure_value_is_formatted(self, value: str) -> str:
46
+ """
47
+ Ensures the value object `value` is stored without separators.
48
+
49
+ Args:
50
+ value (str): The provided value.
51
+
52
+ Returns:
53
+ str: Formatted value.
54
+ """
55
+ return self._IDENTIFICATION_REGEX.sub(repl=r'\1\2', string=value)
56
+
44
57
  @validation(order=0)
45
- def _ensure_value_is_passport(self, value: str) -> None:
58
+ def _ensure_value_follows_identification_regex(self, value: str) -> None:
46
59
  """
47
- Ensures the value object `value` is a Spanish passport.
60
+ Ensures the value object `value` follows the identification regex.
48
61
 
49
62
  Args:
50
63
  value (str): The provided value.
51
64
 
52
65
  Raises:
53
- ValueError: If the `value` is not a Spanish passport.
66
+ ValueError: If the `value` does not follow the identification regex.
54
67
  """
55
- match = self.__PASSPORT_VALUE_OBJECT_REGEX.fullmatch(string=value)
56
- if not match:
68
+ if not self._IDENTIFICATION_REGEX.fullmatch(string=value):
57
69
  self._raise_value_is_not_passport(value=value)
58
70
 
59
71
  def _raise_value_is_not_passport(self, value: str) -> NoReturn:
@@ -67,3 +79,13 @@ class PassportValueObject(NotEmptyStringValueObject, TrimmedStringValueObject):
67
79
  ValueError: If the `value` is not a Spanish passport.
68
80
  """
69
81
  raise ValueError(f'PassportValueObject value <<<{value}>>> is not a valid Spanish passport.')
82
+
83
+ @classmethod
84
+ def regex(cls) -> Pattern[str]:
85
+ """
86
+ Returns a list of regex patterns used for validation.
87
+
88
+ Returns:
89
+ Pattern[str]: List of regex patterns.
90
+ """
91
+ return cls._IDENTIFICATION_REGEX