JsonhPy 2.4__tar.gz → 2.5__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: JsonhPy
3
- Version: 2.4
3
+ Version: 2.5
4
4
  Summary: JSON for Humans in Python.
5
5
  Author-email: Joyless <joyless.mod@gmail.com>
6
6
  License-Expression: MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "JsonhPy"
3
- version = "2.4"
3
+ version = "2.5"
4
4
  authors = [
5
5
  { name="Joyless", email="joyless.mod@gmail.com" },
6
6
  ]
@@ -547,7 +547,7 @@ class JsonhReader:
547
547
  case _:
548
548
  return JsonhResult.from_error("Token type not implemented")
549
549
 
550
- next_element = parse_next_element()
550
+ next_element: JsonhResult[object, str] = parse_next_element()
551
551
 
552
552
  # Ensure exactly one element
553
553
  if not next_element.is_error:
@@ -566,123 +566,136 @@ class JsonhReader:
566
566
 
567
567
  If `indent` is not null, the output is pretty-printed with the given indentation.
568
568
 
569
- The result is not safe to embed in HTML.
569
+ Note: The result is **NOT** safe to embed in HTML. To safely embed in HTML, you need to escape characters like `<`, `>` and `&`.
570
570
  """
571
571
 
572
- current_depth: int = 0
573
- isStartOfStructure: bool = True
574
- is_property_value: bool = False
572
+ def parse_next_element_as_json() -> JsonhResult[str, str]:
573
+ current_depth: int = 0
574
+ isStartOfStructure: bool = True
575
+ is_property_value: bool = False
575
576
 
576
- resultBuilder: str = ""
577
+ result_builder: str = ""
577
578
 
578
- for token_result in self.read_element():
579
- # Check error
580
- if (token_result.is_error):
581
- return JsonhResult.from_error(token_result.error())
582
- token: JsonhToken = token_result.value()
583
-
584
- # Add comments and indents
585
- if not is_property_value:
586
- # Add comma before property/item
587
- if (token.json_type not in [JsonTokenType.NONE, JsonTokenType.COMMENT]) and (current_depth > 0) and (not isStartOfStructure):
588
- # Don't add trailing comma
589
- if token.json_type not in [JsonTokenType.END_OBJECT, JsonTokenType.END_ARRAY]:
590
- resultBuilder += ','
591
-
592
- # Apply indentation
593
- if indent != None:
594
- # Don't indent inside empty structures
595
- if not (token.json_type in [JsonTokenType.END_OBJECT, JsonTokenType.END_ARRAY] and isStartOfStructure):
596
- # Don't indent comment if not included
597
- if (not (token.json_type == JsonTokenType.COMMENT and (not include_comments))):
598
- # Don't indent root elements
599
- if current_depth > 0:
600
- # Add newline before element
601
- resultBuilder += '\n'
602
-
603
- # Get current indent count
604
- indent_count: int = current_depth
605
- if token.json_type in [JsonTokenType.END_OBJECT, JsonTokenType.END_ARRAY]:
606
- indent_count -= 1
607
-
608
- # Add indent
609
- for _ in range(0, indent_count):
610
- resultBuilder += indent
611
- # Track start of structure to avoid adding leading comma
612
- if token.json_type not in [JsonTokenType.NONE, JsonTokenType.COMMENT]:
613
- isStartOfStructure = False
614
- if token.json_type in [JsonTokenType.START_OBJECT, JsonTokenType.START_ARRAY]:
615
- isStartOfStructure = True
616
-
617
- match token.json_type:
618
- # Null
619
- case JsonTokenType.NONE:
620
- resultBuilder += "null"
621
- if current_depth == 0:
622
- return JsonhResult.from_value(resultBuilder)
623
- # True
624
- case JsonTokenType.TRUE:
625
- resultBuilder += "true"
626
- if current_depth == 0:
627
- return JsonhResult.from_value(resultBuilder)
628
- # False
629
- case JsonTokenType.FALSE:
630
- resultBuilder += "false"
631
- if current_depth == 0:
632
- return JsonhResult.from_value(resultBuilder)
633
- # String
634
- case JsonTokenType.STRING:
635
- resultBuilder += json.dumps(token.value, ensure_ascii=False)
636
- if current_depth == 0:
637
- return JsonhResult.from_value(resultBuilder)
638
- # Number
639
- case JsonTokenType.NUMBER:
640
- result: JsonhResult[float] = JsonhNumberParser.parse(token_result.value().value)
641
- if (result.is_error):
642
- return JsonhResult.from_error(result.error())
643
- resultBuilder += str(result.value())
644
- if current_depth == 0:
645
- return JsonhResult.from_value(resultBuilder)
646
- # Start Object
647
- case JsonTokenType.START_OBJECT:
648
- resultBuilder += '{'
649
- current_depth += 1
650
- # Start Array
651
- case JsonTokenType.START_ARRAY:
652
- resultBuilder += '['
653
- current_depth += 1
654
- # End Object
655
- case JsonTokenType.END_OBJECT:
656
- resultBuilder += '}'
657
- current_depth -= 1
658
- if current_depth == 0:
659
- return JsonhResult.from_value(resultBuilder)
660
- # End Array
661
- case JsonTokenType.END_ARRAY:
662
- resultBuilder += ']'
663
- current_depth -= 1
664
- if current_depth == 0:
665
- return JsonhResult.from_value(resultBuilder)
666
- # Property Name
667
- case JsonTokenType.PROPERTY_NAME:
668
- resultBuilder += json.dumps(token.value, ensure_ascii=False)
669
- resultBuilder += ':'
579
+ for token_result in self.read_element():
580
+ # Check error
581
+ if (token_result.is_error):
582
+ return JsonhResult.from_error(token_result.error())
583
+ token: JsonhToken = token_result.value()
584
+
585
+ # Add comments and indents
586
+ if not is_property_value:
587
+ # Add comma before property/item
588
+ if (token.json_type not in [JsonTokenType.NONE, JsonTokenType.COMMENT]) and (current_depth > 0) and (not isStartOfStructure):
589
+ # Don't add trailing comma
590
+ if token.json_type not in [JsonTokenType.END_OBJECT, JsonTokenType.END_ARRAY]:
591
+ result_builder += ','
592
+
593
+ # Apply indentation
670
594
  if indent != None:
671
- resultBuilder += ' '
672
- # Comment
673
- case JsonTokenType.COMMENT:
674
- if (include_comments):
675
- resultBuilder += "/*"
676
- resultBuilder += token.value.replace("/*", "/ *").replace("*/", "* /")
677
- resultBuilder += "*/"
678
- # Not implemented
679
- case _:
680
- return JsonhResult.from_error("Token type not implemented")
681
-
682
- is_property_value = token.json_type == JsonTokenType.PROPERTY_NAME
683
-
684
- # End of input
685
- return JsonhResult.from_error("Expected token, got end of input")
595
+ # Don't indent inside empty structures
596
+ if not (token.json_type in [JsonTokenType.END_OBJECT, JsonTokenType.END_ARRAY] and isStartOfStructure):
597
+ # Don't indent comment if not included
598
+ if (not (token.json_type == JsonTokenType.COMMENT and (not include_comments))):
599
+ # Don't indent root elements
600
+ if current_depth > 0:
601
+ # Add newline before element
602
+ result_builder += '\n'
603
+
604
+ # Get current indent count
605
+ indent_count: int = current_depth
606
+ if token.json_type in [JsonTokenType.END_OBJECT, JsonTokenType.END_ARRAY]:
607
+ indent_count -= 1
608
+
609
+ # Add indent
610
+ for _ in range(0, indent_count):
611
+ result_builder += indent
612
+ # Track start of structure to avoid adding leading comma
613
+ if token.json_type not in [JsonTokenType.NONE, JsonTokenType.COMMENT]:
614
+ isStartOfStructure = False
615
+ if token.json_type in [JsonTokenType.START_OBJECT, JsonTokenType.START_ARRAY]:
616
+ isStartOfStructure = True
617
+
618
+ match token.json_type:
619
+ # Null
620
+ case JsonTokenType.NONE:
621
+ result_builder += "null"
622
+ if current_depth == 0:
623
+ return JsonhResult.from_value(result_builder)
624
+ # True
625
+ case JsonTokenType.TRUE:
626
+ result_builder += "true"
627
+ if current_depth == 0:
628
+ return JsonhResult.from_value(result_builder)
629
+ # False
630
+ case JsonTokenType.FALSE:
631
+ result_builder += "false"
632
+ if current_depth == 0:
633
+ return JsonhResult.from_value(result_builder)
634
+ # String
635
+ case JsonTokenType.STRING:
636
+ result_builder += json.dumps(token.value, ensure_ascii=False)
637
+ if current_depth == 0:
638
+ return JsonhResult.from_value(result_builder)
639
+ # Number
640
+ case JsonTokenType.NUMBER:
641
+ result: JsonhResult[float] = JsonhNumberParser.parse(token_result.value().value)
642
+ if (result.is_error):
643
+ return JsonhResult.from_error(result.error())
644
+ result_builder += str(result.value()).removesuffix(".0")
645
+ if current_depth == 0:
646
+ return JsonhResult.from_value(result_builder)
647
+ # Start Object
648
+ case JsonTokenType.START_OBJECT:
649
+ result_builder += '{'
650
+ current_depth += 1
651
+ # Start Array
652
+ case JsonTokenType.START_ARRAY:
653
+ result_builder += '['
654
+ current_depth += 1
655
+ # End Object
656
+ case JsonTokenType.END_OBJECT:
657
+ result_builder += '}'
658
+ current_depth -= 1
659
+ if current_depth == 0:
660
+ return JsonhResult.from_value(result_builder)
661
+ # End Array
662
+ case JsonTokenType.END_ARRAY:
663
+ result_builder += ']'
664
+ current_depth -= 1
665
+ if current_depth == 0:
666
+ return JsonhResult.from_value(result_builder)
667
+ # Property Name
668
+ case JsonTokenType.PROPERTY_NAME:
669
+ result_builder += json.dumps(token.value, ensure_ascii=False)
670
+ result_builder += ':'
671
+ if indent != None:
672
+ result_builder += ' '
673
+ # Comment
674
+ case JsonTokenType.COMMENT:
675
+ if (include_comments):
676
+ result_builder += "/*"
677
+ result_builder += token.value.replace("/*", "/ *").replace("*/", "* /")
678
+ result_builder += "*/"
679
+ # Not implemented
680
+ case _:
681
+ return JsonhResult.from_error("Token type not implemented")
682
+
683
+ if token.json_type != JsonTokenType.COMMENT:
684
+ is_property_value = token.json_type == JsonTokenType.PROPERTY_NAME
685
+
686
+ # End of input
687
+ return JsonhResult.from_error("Expected token, got end of input")
688
+
689
+ next_element_as_json: JsonhResult[str, str] = parse_next_element_as_json()
690
+
691
+ # Ensure exactly one element
692
+ if not next_element_as_json.is_error:
693
+ if self.options.parse_single_element:
694
+ for token in self.read_end_of_elements():
695
+ if token.is_error:
696
+ return JsonhResult.from_error(token.error())
697
+
698
+ return next_element_as_json
686
699
 
687
700
  def find_property_value(self, property_name: str) -> bool:
688
701
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: JsonhPy
3
- Version: 2.4
3
+ Version: 2.5
4
4
  Summary: JSON for Humans in Python.
5
5
  Author-email: Joyless <joyless.mod@gmail.com>
6
6
  License-Expression: MIT
File without changes
File without changes
File without changes
File without changes