headson 0.2.5__tar.gz → 0.3.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.
Potentially problematic release.
This version of headson might be problematic. Click here for more details.
- {headson-0.2.5 → headson-0.3.0}/Cargo.lock +1 -1
- {headson-0.2.5 → headson-0.3.0}/Cargo.toml +1 -1
- headson-0.3.0/PKG-INFO +168 -0
- headson-0.3.0/README.md +152 -0
- {headson-0.2.5 → headson-0.3.0}/pyproject.toml +2 -4
- {headson-0.2.5 → headson-0.3.0}/python/Cargo.lock +2 -2
- {headson-0.2.5 → headson-0.3.0}/python/Cargo.toml +1 -1
- {headson-0.2.5 → headson-0.3.0}/python/src/lib.rs +8 -7
- {headson-0.2.5 → headson-0.3.0}/src/main.rs +8 -6
- {headson-0.2.5 → headson-0.3.0}/src/order/build.rs +7 -1
- {headson-0.2.5 → headson-0.3.0}/src/order/types.rs +2 -0
- {headson-0.2.5 → headson-0.3.0}/src/serialization/mod.rs +81 -10
- {headson-0.2.5 → headson-0.3.0}/src/serialization/templates/core.rs +6 -1
- {headson-0.2.5 → headson-0.3.0}/src/serialization/templates/js.rs +7 -4
- {headson-0.2.5 → headson-0.3.0}/src/serialization/templates/mod.rs +1 -0
- {headson-0.2.5 → headson-0.3.0}/src/serialization/templates/pseudo.rs +3 -0
- {headson-0.2.5 → headson-0.3.0}/src/serialization/types.rs +2 -0
- {headson-0.2.5 → headson-0.3.0}/src/utils/tree_arena.rs +2 -3
- headson-0.2.5/PKG-INFO +0 -99
- headson-0.2.5/README.md +0 -83
- {headson-0.2.5 → headson-0.3.0}/JSONTestSuite/LICENSE +0 -0
- {headson-0.2.5 → headson-0.3.0}/JSONTestSuite/README.md +0 -0
- {headson-0.2.5 → headson-0.3.0}/LICENSE +0 -0
- {headson-0.2.5 → headson-0.3.0}/python/README.md +0 -0
- {headson-0.2.5 → headson-0.3.0}/python/headson/__init__.py +0 -0
- {headson-0.2.5 → headson-0.3.0}/src/json_ingest/builder.rs +0 -0
- {headson-0.2.5 → headson-0.3.0}/src/json_ingest/mod.rs +0 -0
- {headson-0.2.5 → headson-0.3.0}/src/lib.rs +0 -0
- {headson-0.2.5 → headson-0.3.0}/src/order/mod.rs +0 -0
- {headson-0.2.5 → headson-0.3.0}/src/order/scoring.rs +0 -0
- {headson-0.2.5 → headson-0.3.0}/src/order/snapshots/headson__order__build__tests__order_empty_array_order.snap +0 -0
- {headson-0.2.5 → headson-0.3.0}/src/order/snapshots/headson__order__build__tests__order_single_string_array_order.snap +0 -0
- {headson-0.2.5 → headson-0.3.0}/src/serialization/snapshots/headson__serialization__tests__arena_render_empty.snap +0 -0
- {headson-0.2.5 → headson-0.3.0}/src/serialization/snapshots/headson__serialization__tests__arena_render_single.snap +0 -0
- {headson-0.2.5 → headson-0.3.0}/src/serialization/templates/json.rs +0 -0
- {headson-0.2.5 → headson-0.3.0}/src/snapshots/headson__order__tests__order_empty_array_order.snap +0 -0
- {headson-0.2.5 → headson-0.3.0}/src/snapshots/headson__order__tests__order_single_string_array_order.snap +0 -0
- {headson-0.2.5 → headson-0.3.0}/src/snapshots/headson__order__tests__pq_empty_array_queue.snap +0 -0
- {headson-0.2.5 → headson-0.3.0}/src/snapshots/headson__order__tests__pq_single_string_array_queue.snap +0 -0
- {headson-0.2.5 → headson-0.3.0}/src/snapshots/headson__queue__tests__pq_empty_array_queue.snap +0 -0
- {headson-0.2.5 → headson-0.3.0}/src/snapshots/headson__queue__tests__pq_single_string_array_queue.snap +0 -0
- {headson-0.2.5 → headson-0.3.0}/src/snapshots/headson__tree__tests__build_tree_empty.snap +0 -0
- {headson-0.2.5 → headson-0.3.0}/src/snapshots/headson__tree__tests__build_tree_single.snap +0 -0
- {headson-0.2.5 → headson-0.3.0}/src/utils/graph.rs +0 -0
- {headson-0.2.5 → headson-0.3.0}/src/utils/json.rs +0 -0
- {headson-0.2.5 → headson-0.3.0}/src/utils/mod.rs +0 -0
- {headson-0.2.5 → headson-0.3.0}/src/utils/search.rs +0 -0
- {headson-0.2.5 → headson-0.3.0}/src/utils/text.rs +0 -0
headson-0.3.0/PKG-INFO
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: headson
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Classifier: Programming Language :: Python
|
|
5
|
+
Classifier: Programming Language :: Python :: 3
|
|
6
|
+
Classifier: Programming Language :: Rust
|
|
7
|
+
Classifier: Operating System :: OS Independent
|
|
8
|
+
Requires-Dist: pytest>=8 ; extra == 'test'
|
|
9
|
+
Provides-Extra: test
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Summary: Budget‑constrained JSON preview renderer (Python bindings)
|
|
12
|
+
Keywords: json,preview,summarize,cli,bindings
|
|
13
|
+
Requires-Python: >=3.8
|
|
14
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
15
|
+
|
|
16
|
+
# headson
|
|
17
|
+
|
|
18
|
+
Head/tail for JSON — but structure‑aware. Get a compact preview that shows both the shape and representative values of your data, all within a strict character budget.
|
|
19
|
+
|
|
20
|
+
Available as:
|
|
21
|
+
- CLI (see [Usage](#usage))
|
|
22
|
+
- Python library (see [Python Bindings](#python-bindings))
|
|
23
|
+
|
|
24
|
+
## Install
|
|
25
|
+
|
|
26
|
+
Using Cargo:
|
|
27
|
+
|
|
28
|
+
cargo install headson
|
|
29
|
+
|
|
30
|
+
From source:
|
|
31
|
+
|
|
32
|
+
cargo build --release
|
|
33
|
+
target/release/headson --help
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
## Features
|
|
37
|
+
|
|
38
|
+
- *Budgeted output*: specify exactly how much JSON you want to see
|
|
39
|
+
- *Multiple output formats* : `json` (machine‑readable), `pseudo` (human‑friendly), `js` (valid JavaScript, most detailed metadata).
|
|
40
|
+
- *Multiple inputs*: preview many files at once with a shared or per‑file budget.
|
|
41
|
+
- *Fast*: can process gigabyte-scale files in seconds (mostly disk-constrained)
|
|
42
|
+
- *Available as a CLI app and as a Python library*
|
|
43
|
+
|
|
44
|
+
## Fits into command line workflows
|
|
45
|
+
|
|
46
|
+
If you’re comfortable with tools like `head` and `tail`, use `headson` when you want a quick, structured peek into a JSON file without dumping the entire thing.
|
|
47
|
+
|
|
48
|
+
- `head`/`tail` operate on bytes/lines - their output is not optimized for tree structures
|
|
49
|
+
- `jq` you need to craft filters to preview large JSON files
|
|
50
|
+
- `headson` is like head/tail for trees: zero config but it keeps structure and represents content as much as possible
|
|
51
|
+
|
|
52
|
+
## Usage
|
|
53
|
+
|
|
54
|
+
headson [FLAGS] [INPUT...]
|
|
55
|
+
|
|
56
|
+
- INPUT (optional, repeatable): file path(s). If omitted, reads JSON from stdin. Multiple input files are supported.
|
|
57
|
+
- Prints the preview to stdout. On parse errors, exits non‑zero and prints an error to stderr.
|
|
58
|
+
|
|
59
|
+
Common flags:
|
|
60
|
+
|
|
61
|
+
- `-n, --budget <BYTES>`: per‑file output budget. When multiple input files are provided, the total budget equals `<BYTES> * number_of_inputs`.
|
|
62
|
+
- `-N, --global-budget <BYTES>`: total output budget across all inputs. Useful when you want a fixed-size preview across many files (may omit entire files). Mutually exclusive with `--budget`.
|
|
63
|
+
- `-f, --template <json|pseudo|js>`: output style (default: `pseudo`)
|
|
64
|
+
- `-m, --compact`: no indentation, no spaces, no newlines
|
|
65
|
+
- `--no-newline`: single line output
|
|
66
|
+
- `--no-space`: no space after `:` in objects
|
|
67
|
+
- `--indent <STR>`: indentation unit (default: two spaces)
|
|
68
|
+
- `--string-cap <N>`: max graphemes to consider per string (default: 500)
|
|
69
|
+
- `--tail`: prefer the end of arrays when truncating. Strings are unaffected. In `pseudo`/`js` templates the omission marker appears at the start; `json` remains strict JSON with no annotations.
|
|
70
|
+
|
|
71
|
+
Notes:
|
|
72
|
+
|
|
73
|
+
- With multiple input files:
|
|
74
|
+
- JSON template outputs a single JSON object keyed by the input file paths.
|
|
75
|
+
- Pseudo and JS templates render file sections with human-readable headers.
|
|
76
|
+
- Using `--global-budget` may truncate or omit entire files to respect the total budget.
|
|
77
|
+
- The tool finds the largest preview that fits the budget; if even the tiniest preview exceeds it, you still get a minimal, valid preview.
|
|
78
|
+
- When passing file paths, directories and binary files are ignored; a notice is printed to stderr for each (e.g., `Ignored binary file: ./path/to/file`). Stdin mode reads the stream as-is.
|
|
79
|
+
|
|
80
|
+
Quick one‑liners:
|
|
81
|
+
|
|
82
|
+
- Peek a big JSON stream (keeps structure):
|
|
83
|
+
|
|
84
|
+
zstdcat huge.json.zst | headson -n 800 -f pseudo
|
|
85
|
+
|
|
86
|
+
- Many files with a fixed overall size:
|
|
87
|
+
|
|
88
|
+
headson -N 1200 -f json logs/*.json
|
|
89
|
+
|
|
90
|
+
- Glance at a file, JavaScript‑style comments for omissions:
|
|
91
|
+
|
|
92
|
+
headson -n 400 -f js data.json
|
|
93
|
+
|
|
94
|
+
Show help:
|
|
95
|
+
|
|
96
|
+
headson --help
|
|
97
|
+
|
|
98
|
+
## Examples: head vs headson
|
|
99
|
+
|
|
100
|
+
Input:
|
|
101
|
+
|
|
102
|
+
```json
|
|
103
|
+
{"users":[{"id":1,"name":"Ana","roles":["admin","dev"]},{"id":2,"name":"Bo"}],"meta":{"count":2,"source":"db"}}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Naive cut (can break mid‑token):
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
jq -c . users.json | head -c 80
|
|
110
|
+
# {"users":[{"id":1,"name":"Ana","roles":["admin","dev"]},{"id":2,"name":"Bo"}],"me
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Structured preview with headson (pseudo):
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
headson -n 120 -f pseudo users.json
|
|
117
|
+
# {
|
|
118
|
+
# users: [
|
|
119
|
+
# { id: 1, name: "Ana", roles: [ "admin", … ] },
|
|
120
|
+
# …
|
|
121
|
+
# ]
|
|
122
|
+
# meta: { count: 2, … }
|
|
123
|
+
# }
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Machine‑readable preview (json):
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
headson -n 120 -f json users.json
|
|
130
|
+
# {"users":[{"id":1,"name":"Ana","roles":["admin"]}],"meta":{"count":2}}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Python Bindings
|
|
134
|
+
|
|
135
|
+
A thin Python extension module is available on PyPI as `headson`.
|
|
136
|
+
|
|
137
|
+
- Install: `pip install headson` (prebuilt wheels for CPython 3.10–3.12 on Linux/macOS/Windows). Older/newer Python versions may build from source if Rust is installed.
|
|
138
|
+
- API:
|
|
139
|
+
- `headson.summarize(text: str, *, template: str = "pseudo", character_budget: int | None = None, tail: bool = False) -> str`
|
|
140
|
+
- `template`: one of `"json" | "pseudo" | "js"`
|
|
141
|
+
- `character_budget`: maximum output size in characters (default: 500)
|
|
142
|
+
- `tail`: prefer the end of arrays when truncating; strings unaffected. Affects only display templates (`pseudo`/`js`); `json` remains strict.
|
|
143
|
+
|
|
144
|
+
Example:
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
import json
|
|
148
|
+
import headson
|
|
149
|
+
|
|
150
|
+
data = {"foo": [1, 2, 3], "bar": {"x": "y"}}
|
|
151
|
+
preview = headson.summarize(json.dumps(data), template="json", character_budget=200)
|
|
152
|
+
print(preview)
|
|
153
|
+
|
|
154
|
+
# Prefer the tail of arrays (annotations show in pseudo/js only)
|
|
155
|
+
print(
|
|
156
|
+
headson.summarize(
|
|
157
|
+
json.dumps(list(range(100))),
|
|
158
|
+
template="pseudo",
|
|
159
|
+
character_budget=80,
|
|
160
|
+
tail=True,
|
|
161
|
+
)
|
|
162
|
+
)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## License
|
|
166
|
+
|
|
167
|
+
MIT
|
|
168
|
+
|
headson-0.3.0/README.md
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# headson
|
|
2
|
+
|
|
3
|
+
Head/tail for JSON — but structure‑aware. Get a compact preview that shows both the shape and representative values of your data, all within a strict character budget.
|
|
4
|
+
|
|
5
|
+
Available as:
|
|
6
|
+
- CLI (see [Usage](#usage))
|
|
7
|
+
- Python library (see [Python Bindings](#python-bindings))
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
Using Cargo:
|
|
12
|
+
|
|
13
|
+
cargo install headson
|
|
14
|
+
|
|
15
|
+
From source:
|
|
16
|
+
|
|
17
|
+
cargo build --release
|
|
18
|
+
target/release/headson --help
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
## Features
|
|
22
|
+
|
|
23
|
+
- *Budgeted output*: specify exactly how much JSON you want to see
|
|
24
|
+
- *Multiple output formats* : `json` (machine‑readable), `pseudo` (human‑friendly), `js` (valid JavaScript, most detailed metadata).
|
|
25
|
+
- *Multiple inputs*: preview many files at once with a shared or per‑file budget.
|
|
26
|
+
- *Fast*: can process gigabyte-scale files in seconds (mostly disk-constrained)
|
|
27
|
+
- *Available as a CLI app and as a Python library*
|
|
28
|
+
|
|
29
|
+
## Fits into command line workflows
|
|
30
|
+
|
|
31
|
+
If you’re comfortable with tools like `head` and `tail`, use `headson` when you want a quick, structured peek into a JSON file without dumping the entire thing.
|
|
32
|
+
|
|
33
|
+
- `head`/`tail` operate on bytes/lines - their output is not optimized for tree structures
|
|
34
|
+
- `jq` you need to craft filters to preview large JSON files
|
|
35
|
+
- `headson` is like head/tail for trees: zero config but it keeps structure and represents content as much as possible
|
|
36
|
+
|
|
37
|
+
## Usage
|
|
38
|
+
|
|
39
|
+
headson [FLAGS] [INPUT...]
|
|
40
|
+
|
|
41
|
+
- INPUT (optional, repeatable): file path(s). If omitted, reads JSON from stdin. Multiple input files are supported.
|
|
42
|
+
- Prints the preview to stdout. On parse errors, exits non‑zero and prints an error to stderr.
|
|
43
|
+
|
|
44
|
+
Common flags:
|
|
45
|
+
|
|
46
|
+
- `-n, --budget <BYTES>`: per‑file output budget. When multiple input files are provided, the total budget equals `<BYTES> * number_of_inputs`.
|
|
47
|
+
- `-N, --global-budget <BYTES>`: total output budget across all inputs. Useful when you want a fixed-size preview across many files (may omit entire files). Mutually exclusive with `--budget`.
|
|
48
|
+
- `-f, --template <json|pseudo|js>`: output style (default: `pseudo`)
|
|
49
|
+
- `-m, --compact`: no indentation, no spaces, no newlines
|
|
50
|
+
- `--no-newline`: single line output
|
|
51
|
+
- `--no-space`: no space after `:` in objects
|
|
52
|
+
- `--indent <STR>`: indentation unit (default: two spaces)
|
|
53
|
+
- `--string-cap <N>`: max graphemes to consider per string (default: 500)
|
|
54
|
+
- `--tail`: prefer the end of arrays when truncating. Strings are unaffected. In `pseudo`/`js` templates the omission marker appears at the start; `json` remains strict JSON with no annotations.
|
|
55
|
+
|
|
56
|
+
Notes:
|
|
57
|
+
|
|
58
|
+
- With multiple input files:
|
|
59
|
+
- JSON template outputs a single JSON object keyed by the input file paths.
|
|
60
|
+
- Pseudo and JS templates render file sections with human-readable headers.
|
|
61
|
+
- Using `--global-budget` may truncate or omit entire files to respect the total budget.
|
|
62
|
+
- The tool finds the largest preview that fits the budget; if even the tiniest preview exceeds it, you still get a minimal, valid preview.
|
|
63
|
+
- When passing file paths, directories and binary files are ignored; a notice is printed to stderr for each (e.g., `Ignored binary file: ./path/to/file`). Stdin mode reads the stream as-is.
|
|
64
|
+
|
|
65
|
+
Quick one‑liners:
|
|
66
|
+
|
|
67
|
+
- Peek a big JSON stream (keeps structure):
|
|
68
|
+
|
|
69
|
+
zstdcat huge.json.zst | headson -n 800 -f pseudo
|
|
70
|
+
|
|
71
|
+
- Many files with a fixed overall size:
|
|
72
|
+
|
|
73
|
+
headson -N 1200 -f json logs/*.json
|
|
74
|
+
|
|
75
|
+
- Glance at a file, JavaScript‑style comments for omissions:
|
|
76
|
+
|
|
77
|
+
headson -n 400 -f js data.json
|
|
78
|
+
|
|
79
|
+
Show help:
|
|
80
|
+
|
|
81
|
+
headson --help
|
|
82
|
+
|
|
83
|
+
## Examples: head vs headson
|
|
84
|
+
|
|
85
|
+
Input:
|
|
86
|
+
|
|
87
|
+
```json
|
|
88
|
+
{"users":[{"id":1,"name":"Ana","roles":["admin","dev"]},{"id":2,"name":"Bo"}],"meta":{"count":2,"source":"db"}}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Naive cut (can break mid‑token):
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
jq -c . users.json | head -c 80
|
|
95
|
+
# {"users":[{"id":1,"name":"Ana","roles":["admin","dev"]},{"id":2,"name":"Bo"}],"me
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Structured preview with headson (pseudo):
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
headson -n 120 -f pseudo users.json
|
|
102
|
+
# {
|
|
103
|
+
# users: [
|
|
104
|
+
# { id: 1, name: "Ana", roles: [ "admin", … ] },
|
|
105
|
+
# …
|
|
106
|
+
# ]
|
|
107
|
+
# meta: { count: 2, … }
|
|
108
|
+
# }
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Machine‑readable preview (json):
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
headson -n 120 -f json users.json
|
|
115
|
+
# {"users":[{"id":1,"name":"Ana","roles":["admin"]}],"meta":{"count":2}}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Python Bindings
|
|
119
|
+
|
|
120
|
+
A thin Python extension module is available on PyPI as `headson`.
|
|
121
|
+
|
|
122
|
+
- Install: `pip install headson` (prebuilt wheels for CPython 3.10–3.12 on Linux/macOS/Windows). Older/newer Python versions may build from source if Rust is installed.
|
|
123
|
+
- API:
|
|
124
|
+
- `headson.summarize(text: str, *, template: str = "pseudo", character_budget: int | None = None, tail: bool = False) -> str`
|
|
125
|
+
- `template`: one of `"json" | "pseudo" | "js"`
|
|
126
|
+
- `character_budget`: maximum output size in characters (default: 500)
|
|
127
|
+
- `tail`: prefer the end of arrays when truncating; strings unaffected. Affects only display templates (`pseudo`/`js`); `json` remains strict.
|
|
128
|
+
|
|
129
|
+
Example:
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
import json
|
|
133
|
+
import headson
|
|
134
|
+
|
|
135
|
+
data = {"foo": [1, 2, 3], "bar": {"x": "y"}}
|
|
136
|
+
preview = headson.summarize(json.dumps(data), template="json", character_budget=200)
|
|
137
|
+
print(preview)
|
|
138
|
+
|
|
139
|
+
# Prefer the tail of arrays (annotations show in pseudo/js only)
|
|
140
|
+
print(
|
|
141
|
+
headson.summarize(
|
|
142
|
+
json.dumps(list(range(100))),
|
|
143
|
+
template="pseudo",
|
|
144
|
+
character_budget=80,
|
|
145
|
+
tail=True,
|
|
146
|
+
)
|
|
147
|
+
)
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## License
|
|
151
|
+
|
|
152
|
+
MIT
|
|
@@ -4,7 +4,7 @@ build-backend = "maturin"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "headson"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.0"
|
|
8
8
|
description = "Budget‑constrained JSON preview renderer (Python bindings)"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.8"
|
|
@@ -32,7 +32,7 @@ python-source = "python"
|
|
|
32
32
|
dev = [
|
|
33
33
|
"pytest>=8",
|
|
34
34
|
"maturin>=1.7,<2",
|
|
35
|
-
"ruff
|
|
35
|
+
"ruff==0.6.9",
|
|
36
36
|
]
|
|
37
37
|
|
|
38
38
|
[tool.ruff]
|
|
@@ -42,5 +42,3 @@ src = ["python", "tests_py"]
|
|
|
42
42
|
|
|
43
43
|
[tool.ruff.lint]
|
|
44
44
|
select = ["E", "F"]
|
|
45
|
-
|
|
46
|
-
|
|
@@ -169,7 +169,7 @@ dependencies = [
|
|
|
169
169
|
|
|
170
170
|
[[package]]
|
|
171
171
|
name = "headson"
|
|
172
|
-
version = "0.
|
|
172
|
+
version = "0.3.0"
|
|
173
173
|
dependencies = [
|
|
174
174
|
"anyhow",
|
|
175
175
|
"clap",
|
|
@@ -182,7 +182,7 @@ dependencies = [
|
|
|
182
182
|
|
|
183
183
|
[[package]]
|
|
184
184
|
name = "headson-python"
|
|
185
|
-
version = "0.
|
|
185
|
+
version = "0.3.0"
|
|
186
186
|
dependencies = [
|
|
187
187
|
"anyhow",
|
|
188
188
|
"headson",
|
|
@@ -13,9 +13,7 @@ fn to_template(s: &str) -> Result<OutputTemplate> {
|
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
fn render_config(
|
|
17
|
-
template: &str,
|
|
18
|
-
) -> Result<RenderConfig> {
|
|
16
|
+
fn render_config(template: &str, prefer_tail_arrays: bool) -> Result<RenderConfig> {
|
|
19
17
|
let t = to_template(template)?;
|
|
20
18
|
let space = " ".to_string();
|
|
21
19
|
let newline = "\n".to_string();
|
|
@@ -25,13 +23,15 @@ fn render_config(
|
|
|
25
23
|
indent_unit,
|
|
26
24
|
space,
|
|
27
25
|
newline,
|
|
26
|
+
prefer_tail_arrays,
|
|
28
27
|
})
|
|
29
28
|
}
|
|
30
29
|
|
|
31
|
-
fn priority_config(per_file_budget: usize) -> PriorityConfig {
|
|
30
|
+
fn priority_config(per_file_budget: usize, prefer_tail_arrays: bool) -> PriorityConfig {
|
|
32
31
|
PriorityConfig {
|
|
33
32
|
max_string_graphemes: 500,
|
|
34
33
|
array_max_items: (per_file_budget / 2).max(1),
|
|
34
|
+
prefer_tail_arrays,
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
|
|
@@ -40,17 +40,18 @@ fn to_pyerr(e: anyhow::Error) -> PyErr {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
#[pyfunction]
|
|
43
|
-
#[pyo3(signature = (text, *, template="pseudo", character_budget=None))]
|
|
43
|
+
#[pyo3(signature = (text, *, template="pseudo", character_budget=None, tail=false))]
|
|
44
44
|
fn summarize(
|
|
45
45
|
py: Python<'_>,
|
|
46
46
|
text: &str,
|
|
47
47
|
template: &str,
|
|
48
48
|
character_budget: Option<usize>,
|
|
49
|
+
tail: bool,
|
|
49
50
|
) -> PyResult<String> {
|
|
50
|
-
let cfg = render_config(template).map_err(to_pyerr)?;
|
|
51
|
+
let cfg = render_config(template, tail).map_err(to_pyerr)?;
|
|
51
52
|
let budget = character_budget.unwrap_or(500);
|
|
52
53
|
let per_file_for_priority = budget.max(1);
|
|
53
|
-
let prio = priority_config(per_file_for_priority);
|
|
54
|
+
let prio = priority_config(per_file_for_priority, tail);
|
|
54
55
|
let input = text.as_bytes().to_vec();
|
|
55
56
|
py.detach(|| headson_core::headson(input, &cfg, &prio, budget).map_err(to_pyerr))
|
|
56
57
|
}
|
|
@@ -53,6 +53,12 @@ struct Cli {
|
|
|
53
53
|
help = "Total output budget across all inputs; useful to keep multiple files within a fixed overall output size (may omit entire files)."
|
|
54
54
|
)]
|
|
55
55
|
global_budget: Option<usize>,
|
|
56
|
+
#[arg(
|
|
57
|
+
long = "tail",
|
|
58
|
+
default_value_t = false,
|
|
59
|
+
help = "Prefer the end of arrays when truncating. Strings unaffected; JSON stays strict."
|
|
60
|
+
)]
|
|
61
|
+
tail: bool,
|
|
56
62
|
#[arg(
|
|
57
63
|
value_name = "INPUT",
|
|
58
64
|
value_hint = clap::ValueHint::FilePath,
|
|
@@ -225,6 +231,7 @@ fn get_render_config_from(cli: &Cli) -> headson::RenderConfig {
|
|
|
225
231
|
indent_unit,
|
|
226
232
|
space,
|
|
227
233
|
newline,
|
|
234
|
+
prefer_tail_arrays: cli.tail,
|
|
228
235
|
}
|
|
229
236
|
}
|
|
230
237
|
|
|
@@ -232,14 +239,9 @@ fn get_priority_config(
|
|
|
232
239
|
per_file_budget: usize,
|
|
233
240
|
cli: &Cli,
|
|
234
241
|
) -> headson::PriorityConfig {
|
|
235
|
-
// Optimization: derive a conservative per‑array expansion cap from the output
|
|
236
|
-
// budget to avoid allocating/walking items that could never appear in the
|
|
237
|
-
// final preview. As a simple lower bound, an array of N items needs ~2*N
|
|
238
|
-
// bytes to render (item plus comma), so we cap per‑array expansion at
|
|
239
|
-
// budget/2. This prunes unnecessary work on large inputs without changing
|
|
240
|
-
// output semantics.
|
|
241
242
|
headson::PriorityConfig {
|
|
242
243
|
max_string_graphemes: cli.string_cap,
|
|
243
244
|
array_max_items: (per_file_budget / 2).max(1),
|
|
245
|
+
prefer_tail_arrays: cli.tail,
|
|
244
246
|
}
|
|
245
247
|
}
|
|
@@ -120,7 +120,13 @@ impl<'a> Scope<'a> {
|
|
|
120
120
|
let child_kind = self.arena.nodes[child_arena_id].kind;
|
|
121
121
|
let child_pq = *self.next_pq_id;
|
|
122
122
|
*self.next_pq_id += 1;
|
|
123
|
-
let
|
|
123
|
+
let idx_for_priority: usize = if self.config.prefer_tail_arrays {
|
|
124
|
+
kept.saturating_sub(1).saturating_sub(i)
|
|
125
|
+
} else {
|
|
126
|
+
i
|
|
127
|
+
};
|
|
128
|
+
let ii = idx_for_priority as u128;
|
|
129
|
+
let extra = ii * ii * ii * ARRAY_INDEX_CUBIC_WEIGHT;
|
|
124
130
|
let score = entry.score + ARRAY_CHILD_BASE_INCREMENT + extra;
|
|
125
131
|
let child_node = &self.arena.nodes[child_arena_id];
|
|
126
132
|
self.push_child_common(
|
|
@@ -4,6 +4,7 @@ use serde_json;
|
|
|
4
4
|
pub struct PriorityConfig {
|
|
5
5
|
pub max_string_graphemes: usize,
|
|
6
6
|
pub array_max_items: usize,
|
|
7
|
+
pub prefer_tail_arrays: bool,
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
impl PriorityConfig {
|
|
@@ -11,6 +12,7 @@ impl PriorityConfig {
|
|
|
11
12
|
Self {
|
|
12
13
|
max_string_graphemes,
|
|
13
14
|
array_max_items,
|
|
15
|
+
prefer_tail_arrays: false,
|
|
14
16
|
}
|
|
15
17
|
}
|
|
16
18
|
}
|
|
@@ -19,6 +19,39 @@ pub(crate) struct RenderScope<'a> {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
impl<'a> RenderScope<'a> {
|
|
22
|
+
fn render_has_newline(&self, s: &str) -> bool {
|
|
23
|
+
let nl = &self.config.newline;
|
|
24
|
+
if nl.is_empty() {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
if nl == "\n" {
|
|
28
|
+
return s.as_bytes().contains(&b'\n');
|
|
29
|
+
}
|
|
30
|
+
s.contains(nl)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
fn push_array_child_line(
|
|
34
|
+
&self,
|
|
35
|
+
out: &mut Vec<ArrayChildPair>,
|
|
36
|
+
index: usize,
|
|
37
|
+
child_kind: NodeKind,
|
|
38
|
+
depth: usize,
|
|
39
|
+
rendered: String,
|
|
40
|
+
) {
|
|
41
|
+
if self.render_has_newline(&rendered) {
|
|
42
|
+
out.push((index, rendered));
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
match child_kind {
|
|
46
|
+
NodeKind::Array | NodeKind::Object => {
|
|
47
|
+
out.push((index, rendered));
|
|
48
|
+
}
|
|
49
|
+
_ => {
|
|
50
|
+
let child_indent = indent(depth + 1, &self.config.indent_unit);
|
|
51
|
+
out.push((index, format!("{child_indent}{rendered}")));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
22
55
|
fn append_js_fileset_section(
|
|
23
56
|
&mut self,
|
|
24
57
|
out: &mut String,
|
|
@@ -172,6 +205,7 @@ impl<'a> RenderScope<'a> {
|
|
|
172
205
|
indent_unit: &config.indent_unit,
|
|
173
206
|
inline_open: inline,
|
|
174
207
|
newline: &config.newline,
|
|
208
|
+
omitted_at_start: config.prefer_tail_arrays,
|
|
175
209
|
};
|
|
176
210
|
render_array(config.template, &ctx)
|
|
177
211
|
}
|
|
@@ -278,7 +312,6 @@ impl<'a> RenderScope<'a> {
|
|
|
278
312
|
id: usize,
|
|
279
313
|
depth: usize,
|
|
280
314
|
) -> (Vec<ArrayChildPair>, usize) {
|
|
281
|
-
let config = self.config;
|
|
282
315
|
let mut children_pairs: Vec<ArrayChildPair> = Vec::new();
|
|
283
316
|
let mut kept = 0usize;
|
|
284
317
|
if let Some(children_ids) = self.pq.children.get(id) {
|
|
@@ -287,17 +320,16 @@ impl<'a> RenderScope<'a> {
|
|
|
287
320
|
continue;
|
|
288
321
|
}
|
|
289
322
|
kept += 1;
|
|
323
|
+
let child_kind = self.pq.nodes[child_id.0].kind;
|
|
290
324
|
let rendered =
|
|
291
325
|
self.serialize_node(child_id.0, depth + 1, false);
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
.push((i, format!("{child_indent}{rendered}")));
|
|
300
|
-
}
|
|
326
|
+
self.push_array_child_line(
|
|
327
|
+
&mut children_pairs,
|
|
328
|
+
i,
|
|
329
|
+
child_kind,
|
|
330
|
+
depth,
|
|
331
|
+
rendered,
|
|
332
|
+
);
|
|
301
333
|
}
|
|
302
334
|
}
|
|
303
335
|
(children_pairs, kept)
|
|
@@ -463,11 +495,49 @@ mod tests {
|
|
|
463
495
|
indent_unit: " ".to_string(),
|
|
464
496
|
space: " ".to_string(),
|
|
465
497
|
newline: "\n".to_string(),
|
|
498
|
+
prefer_tail_arrays: false,
|
|
466
499
|
},
|
|
467
500
|
);
|
|
468
501
|
assert_snapshot!("arena_render_empty", out);
|
|
469
502
|
}
|
|
470
503
|
|
|
504
|
+
#[test]
|
|
505
|
+
fn newline_detection_crlf_array_child() {
|
|
506
|
+
// Ensure we exercise the render_has_newline branch that checks
|
|
507
|
+
// arbitrary newline sequences (e.g., "\r\n") via s.contains(nl).
|
|
508
|
+
let arena = crate::json_ingest::build_json_tree_arena(
|
|
509
|
+
"[{\"a\":1,\"b\":2}]",
|
|
510
|
+
&crate::PriorityConfig::new(usize::MAX, usize::MAX),
|
|
511
|
+
)
|
|
512
|
+
.unwrap();
|
|
513
|
+
let build = build_order(
|
|
514
|
+
&arena,
|
|
515
|
+
&crate::PriorityConfig::new(usize::MAX, usize::MAX),
|
|
516
|
+
)
|
|
517
|
+
.unwrap();
|
|
518
|
+
let mut marks = vec![0u32; build.total_nodes];
|
|
519
|
+
let out = render_arena_with_marks(
|
|
520
|
+
&build,
|
|
521
|
+
usize::MAX,
|
|
522
|
+
&mut marks,
|
|
523
|
+
1,
|
|
524
|
+
&crate::RenderConfig {
|
|
525
|
+
template: crate::OutputTemplate::Json,
|
|
526
|
+
indent_unit: " ".to_string(),
|
|
527
|
+
space: " ".to_string(),
|
|
528
|
+
// Use CRLF to force the contains(nl) path.
|
|
529
|
+
newline: "\r\n".to_string(),
|
|
530
|
+
prefer_tail_arrays: false,
|
|
531
|
+
},
|
|
532
|
+
);
|
|
533
|
+
// Sanity: output should contain CRLF newlines and render the object child across lines.
|
|
534
|
+
assert!(
|
|
535
|
+
out.contains("\r\n"),
|
|
536
|
+
"expected CRLF newlines in output: {out:?}"
|
|
537
|
+
);
|
|
538
|
+
assert!(out.starts_with("["));
|
|
539
|
+
}
|
|
540
|
+
|
|
471
541
|
#[test]
|
|
472
542
|
fn arena_render_single_string_array() {
|
|
473
543
|
let arena = crate::json_ingest::build_json_tree_arena(
|
|
@@ -491,6 +561,7 @@ mod tests {
|
|
|
491
561
|
indent_unit: " ".to_string(),
|
|
492
562
|
space: " ".to_string(),
|
|
493
563
|
newline: "\n".to_string(),
|
|
564
|
+
prefer_tail_arrays: false,
|
|
494
565
|
},
|
|
495
566
|
);
|
|
496
567
|
assert_snapshot!("arena_render_single", out);
|
|
@@ -48,8 +48,13 @@ pub fn render_array_with<S: Style>(ctx: &ArrayCtx<'_>) -> String {
|
|
|
48
48
|
out.push_str(open_indent);
|
|
49
49
|
out.push('[');
|
|
50
50
|
out.push_str(ctx.newline);
|
|
51
|
+
if ctx.omitted_at_start {
|
|
52
|
+
S::array_push_omitted(&mut out, ctx);
|
|
53
|
+
}
|
|
51
54
|
push_array_items(&mut out, ctx);
|
|
52
|
-
|
|
55
|
+
if !ctx.omitted_at_start {
|
|
56
|
+
S::array_push_omitted(&mut out, ctx);
|
|
57
|
+
}
|
|
53
58
|
out.push_str(&base);
|
|
54
59
|
out.push(']');
|
|
55
60
|
out
|
|
@@ -18,10 +18,13 @@ impl Style for Js {
|
|
|
18
18
|
fn array_push_omitted(out: &mut String, ctx: &ArrayCtx<'_>) {
|
|
19
19
|
if ctx.omitted > 0 {
|
|
20
20
|
out.push_str(&indent(ctx.depth + 1, ctx.indent_unit));
|
|
21
|
-
out.push_str(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
out.push_str("/* ");
|
|
22
|
+
out.push_str(&ctx.omitted.to_string());
|
|
23
|
+
out.push_str(" more items */");
|
|
24
|
+
if ctx.children_len > 0 && ctx.omitted_at_start {
|
|
25
|
+
out.push(',');
|
|
26
|
+
}
|
|
27
|
+
out.push_str(ctx.newline);
|
|
25
28
|
}
|
|
26
29
|
}
|
|
27
30
|
|
|
@@ -13,4 +13,6 @@ pub struct RenderConfig {
|
|
|
13
13
|
// Newline sequence to use in final output (e.g., "\n" or "").
|
|
14
14
|
// Templates read this directly; no post-processing replacement.
|
|
15
15
|
pub newline: String,
|
|
16
|
+
// When true, arrays prefer tail rendering (omission marker at start).
|
|
17
|
+
pub prefer_tail_arrays: bool,
|
|
16
18
|
}
|
|
@@ -6,9 +6,8 @@ pub struct JsonTreeArena {
|
|
|
6
6
|
pub children: Vec<usize>,
|
|
7
7
|
pub obj_keys: Vec<String>,
|
|
8
8
|
pub root_id: usize,
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
// internal marker for future behaviors.
|
|
9
|
+
// True when root is a synthetic wrapper object for multi-input ingest.
|
|
10
|
+
// Rendering remains standard JSON; used to select fileset-specific headers.
|
|
12
11
|
pub is_fileset: bool,
|
|
13
12
|
}
|
|
14
13
|
|
headson-0.2.5/PKG-INFO
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: headson
|
|
3
|
-
Version: 0.2.5
|
|
4
|
-
Classifier: Programming Language :: Python
|
|
5
|
-
Classifier: Programming Language :: Python :: 3
|
|
6
|
-
Classifier: Programming Language :: Rust
|
|
7
|
-
Classifier: Operating System :: OS Independent
|
|
8
|
-
Requires-Dist: pytest>=8 ; extra == 'test'
|
|
9
|
-
Provides-Extra: test
|
|
10
|
-
License-File: LICENSE
|
|
11
|
-
Summary: Budget‑constrained JSON preview renderer (Python bindings)
|
|
12
|
-
Keywords: json,preview,summarize,cli,bindings
|
|
13
|
-
Requires-Python: >=3.8
|
|
14
|
-
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
15
|
-
|
|
16
|
-
# headson
|
|
17
|
-
|
|
18
|
-
Budget‑constrained JSON preview for the terminal.
|
|
19
|
-
|
|
20
|
-
## Install
|
|
21
|
-
|
|
22
|
-
Using Cargo:
|
|
23
|
-
|
|
24
|
-
cargo install headson
|
|
25
|
-
|
|
26
|
-
From source:
|
|
27
|
-
|
|
28
|
-
cargo build --release
|
|
29
|
-
target/release/headson --help
|
|
30
|
-
|
|
31
|
-
## Usage
|
|
32
|
-
|
|
33
|
-
headson [FLAGS] [INPUT...]
|
|
34
|
-
|
|
35
|
-
- INPUT (optional, repeatable): file path(s). If omitted, reads JSON from stdin. Multiple input files are supported.
|
|
36
|
-
- Prints the preview to stdout. On parse errors, exits non‑zero and prints an error to stderr.
|
|
37
|
-
|
|
38
|
-
Common flags:
|
|
39
|
-
|
|
40
|
-
- `-n, --budget <BYTES>`: per‑file output budget. When multiple input files are provided, the total budget equals `<BYTES> * number_of_inputs`.
|
|
41
|
-
- `-N, --global-budget <BYTES>`: total output budget across all inputs. Useful when you want a fixed-size preview across many files (may omit entire files). Mutually exclusive with `--budget`.
|
|
42
|
-
- `-f, --template <json|pseudo|js>`: output style (default: `pseudo`)
|
|
43
|
-
- `-m, --compact`: no indentation, no spaces, no newlines
|
|
44
|
-
- `--no-newline`: single line output
|
|
45
|
-
- `--no-space`: no space after `:` in objects
|
|
46
|
-
- `--indent <STR>`: indentation unit (default: two spaces)
|
|
47
|
-
- `--string-cap <N>`: max graphemes to consider per string (default: 500)
|
|
48
|
-
|
|
49
|
-
Notes:
|
|
50
|
-
|
|
51
|
-
- With multiple input files:
|
|
52
|
-
- JSON template outputs a single JSON object keyed by the input file paths.
|
|
53
|
-
- Pseudo and JS templates render file sections with human-readable headers.
|
|
54
|
-
- Using `--global-budget` may truncate or omit entire files to respect the total budget.
|
|
55
|
-
- When passing file paths, directories and binary files are ignored; a notice is printed to stderr for each (e.g., `Ignored binary file: ./path/to/file`). Stdin mode reads the stream as-is.
|
|
56
|
-
|
|
57
|
-
Examples:
|
|
58
|
-
|
|
59
|
-
- Read from stdin with defaults:
|
|
60
|
-
|
|
61
|
-
cat data.json | headson
|
|
62
|
-
|
|
63
|
-
- Read from file, JS style, 200‑byte budget:
|
|
64
|
-
|
|
65
|
-
headson -n 200 -f js data.json
|
|
66
|
-
|
|
67
|
-
- JSON style, compact:
|
|
68
|
-
|
|
69
|
-
headson -f json -m data.json
|
|
70
|
-
|
|
71
|
-
- Multiple files (JSON template produces an object keyed by paths):
|
|
72
|
-
|
|
73
|
-
headson -f json a.json b.json
|
|
74
|
-
|
|
75
|
-
- Global limit across files (fixed total size across all files):
|
|
76
|
-
|
|
77
|
-
headson -N 400 -f json a.json b.json
|
|
78
|
-
|
|
79
|
-
Show help:
|
|
80
|
-
|
|
81
|
-
headson --help
|
|
82
|
-
|
|
83
|
-
## Python package
|
|
84
|
-
|
|
85
|
-
Headson is also available as a Python extension module built with PyO3/maturin.
|
|
86
|
-
|
|
87
|
-
Install from PyPI:
|
|
88
|
-
|
|
89
|
-
pip install headson
|
|
90
|
-
|
|
91
|
-
Example:
|
|
92
|
-
|
|
93
|
-
import json
|
|
94
|
-
import headson
|
|
95
|
-
|
|
96
|
-
data = {"foo": [1, 2, 3], "bar": {"x": "y"}}
|
|
97
|
-
preview = headson.summarize(json.dumps(data), template="json", character_budget=200)
|
|
98
|
-
print(preview)
|
|
99
|
-
|
headson-0.2.5/README.md
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
# headson
|
|
2
|
-
|
|
3
|
-
Budget‑constrained JSON preview for the terminal.
|
|
4
|
-
|
|
5
|
-
## Install
|
|
6
|
-
|
|
7
|
-
Using Cargo:
|
|
8
|
-
|
|
9
|
-
cargo install headson
|
|
10
|
-
|
|
11
|
-
From source:
|
|
12
|
-
|
|
13
|
-
cargo build --release
|
|
14
|
-
target/release/headson --help
|
|
15
|
-
|
|
16
|
-
## Usage
|
|
17
|
-
|
|
18
|
-
headson [FLAGS] [INPUT...]
|
|
19
|
-
|
|
20
|
-
- INPUT (optional, repeatable): file path(s). If omitted, reads JSON from stdin. Multiple input files are supported.
|
|
21
|
-
- Prints the preview to stdout. On parse errors, exits non‑zero and prints an error to stderr.
|
|
22
|
-
|
|
23
|
-
Common flags:
|
|
24
|
-
|
|
25
|
-
- `-n, --budget <BYTES>`: per‑file output budget. When multiple input files are provided, the total budget equals `<BYTES> * number_of_inputs`.
|
|
26
|
-
- `-N, --global-budget <BYTES>`: total output budget across all inputs. Useful when you want a fixed-size preview across many files (may omit entire files). Mutually exclusive with `--budget`.
|
|
27
|
-
- `-f, --template <json|pseudo|js>`: output style (default: `pseudo`)
|
|
28
|
-
- `-m, --compact`: no indentation, no spaces, no newlines
|
|
29
|
-
- `--no-newline`: single line output
|
|
30
|
-
- `--no-space`: no space after `:` in objects
|
|
31
|
-
- `--indent <STR>`: indentation unit (default: two spaces)
|
|
32
|
-
- `--string-cap <N>`: max graphemes to consider per string (default: 500)
|
|
33
|
-
|
|
34
|
-
Notes:
|
|
35
|
-
|
|
36
|
-
- With multiple input files:
|
|
37
|
-
- JSON template outputs a single JSON object keyed by the input file paths.
|
|
38
|
-
- Pseudo and JS templates render file sections with human-readable headers.
|
|
39
|
-
- Using `--global-budget` may truncate or omit entire files to respect the total budget.
|
|
40
|
-
- When passing file paths, directories and binary files are ignored; a notice is printed to stderr for each (e.g., `Ignored binary file: ./path/to/file`). Stdin mode reads the stream as-is.
|
|
41
|
-
|
|
42
|
-
Examples:
|
|
43
|
-
|
|
44
|
-
- Read from stdin with defaults:
|
|
45
|
-
|
|
46
|
-
cat data.json | headson
|
|
47
|
-
|
|
48
|
-
- Read from file, JS style, 200‑byte budget:
|
|
49
|
-
|
|
50
|
-
headson -n 200 -f js data.json
|
|
51
|
-
|
|
52
|
-
- JSON style, compact:
|
|
53
|
-
|
|
54
|
-
headson -f json -m data.json
|
|
55
|
-
|
|
56
|
-
- Multiple files (JSON template produces an object keyed by paths):
|
|
57
|
-
|
|
58
|
-
headson -f json a.json b.json
|
|
59
|
-
|
|
60
|
-
- Global limit across files (fixed total size across all files):
|
|
61
|
-
|
|
62
|
-
headson -N 400 -f json a.json b.json
|
|
63
|
-
|
|
64
|
-
Show help:
|
|
65
|
-
|
|
66
|
-
headson --help
|
|
67
|
-
|
|
68
|
-
## Python package
|
|
69
|
-
|
|
70
|
-
Headson is also available as a Python extension module built with PyO3/maturin.
|
|
71
|
-
|
|
72
|
-
Install from PyPI:
|
|
73
|
-
|
|
74
|
-
pip install headson
|
|
75
|
-
|
|
76
|
-
Example:
|
|
77
|
-
|
|
78
|
-
import json
|
|
79
|
-
import headson
|
|
80
|
-
|
|
81
|
-
data = {"foo": [1, 2, 3], "bar": {"x": "y"}}
|
|
82
|
-
preview = headson.summarize(json.dumps(data), template="json", character_budget=200)
|
|
83
|
-
print(preview)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{headson-0.2.5 → headson-0.3.0}/src/snapshots/headson__order__tests__order_empty_array_order.snap
RENAMED
|
File without changes
|
|
File without changes
|
{headson-0.2.5 → headson-0.3.0}/src/snapshots/headson__order__tests__pq_empty_array_queue.snap
RENAMED
|
File without changes
|
|
File without changes
|
{headson-0.2.5 → headson-0.3.0}/src/snapshots/headson__queue__tests__pq_empty_array_queue.snap
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|