hayate-accel 0.1.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.
@@ -0,0 +1,172 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 4
4
+
5
+ [[package]]
6
+ name = "autocfg"
7
+ version = "1.5.1"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
10
+
11
+ [[package]]
12
+ name = "hayate-accel"
13
+ version = "0.1.0"
14
+ dependencies = [
15
+ "pyo3",
16
+ ]
17
+
18
+ [[package]]
19
+ name = "heck"
20
+ version = "0.5.0"
21
+ source = "registry+https://github.com/rust-lang/crates.io-index"
22
+ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
23
+
24
+ [[package]]
25
+ name = "indoc"
26
+ version = "2.0.7"
27
+ source = "registry+https://github.com/rust-lang/crates.io-index"
28
+ checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
29
+ dependencies = [
30
+ "rustversion",
31
+ ]
32
+
33
+ [[package]]
34
+ name = "libc"
35
+ version = "0.2.189"
36
+ source = "registry+https://github.com/rust-lang/crates.io-index"
37
+ checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
38
+
39
+ [[package]]
40
+ name = "memoffset"
41
+ version = "0.9.1"
42
+ source = "registry+https://github.com/rust-lang/crates.io-index"
43
+ checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
44
+ dependencies = [
45
+ "autocfg",
46
+ ]
47
+
48
+ [[package]]
49
+ name = "once_cell"
50
+ version = "1.21.4"
51
+ source = "registry+https://github.com/rust-lang/crates.io-index"
52
+ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
53
+
54
+ [[package]]
55
+ name = "portable-atomic"
56
+ version = "1.14.0"
57
+ source = "registry+https://github.com/rust-lang/crates.io-index"
58
+ checksum = "3d20d5497ef88037a52ff98267d066e7f11fcc5e99bbfbd58a42336193aacec3"
59
+
60
+ [[package]]
61
+ name = "proc-macro2"
62
+ version = "1.0.107"
63
+ source = "registry+https://github.com/rust-lang/crates.io-index"
64
+ checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
65
+ dependencies = [
66
+ "unicode-ident",
67
+ ]
68
+
69
+ [[package]]
70
+ name = "pyo3"
71
+ version = "0.26.0"
72
+ source = "registry+https://github.com/rust-lang/crates.io-index"
73
+ checksum = "7ba0117f4212101ee6544044dae45abe1083d30ce7b29c4b5cbdfa2354e07383"
74
+ dependencies = [
75
+ "indoc",
76
+ "libc",
77
+ "memoffset",
78
+ "once_cell",
79
+ "portable-atomic",
80
+ "pyo3-build-config",
81
+ "pyo3-ffi",
82
+ "pyo3-macros",
83
+ "unindent",
84
+ ]
85
+
86
+ [[package]]
87
+ name = "pyo3-build-config"
88
+ version = "0.26.0"
89
+ source = "registry+https://github.com/rust-lang/crates.io-index"
90
+ checksum = "4fc6ddaf24947d12a9aa31ac65431fb1b851b8f4365426e182901eabfb87df5f"
91
+ dependencies = [
92
+ "target-lexicon",
93
+ ]
94
+
95
+ [[package]]
96
+ name = "pyo3-ffi"
97
+ version = "0.26.0"
98
+ source = "registry+https://github.com/rust-lang/crates.io-index"
99
+ checksum = "025474d3928738efb38ac36d4744a74a400c901c7596199e20e45d98eb194105"
100
+ dependencies = [
101
+ "libc",
102
+ "pyo3-build-config",
103
+ ]
104
+
105
+ [[package]]
106
+ name = "pyo3-macros"
107
+ version = "0.26.0"
108
+ source = "registry+https://github.com/rust-lang/crates.io-index"
109
+ checksum = "2e64eb489f22fe1c95911b77c44cc41e7c19f3082fc81cce90f657cdc42ffded"
110
+ dependencies = [
111
+ "proc-macro2",
112
+ "pyo3-macros-backend",
113
+ "quote",
114
+ "syn",
115
+ ]
116
+
117
+ [[package]]
118
+ name = "pyo3-macros-backend"
119
+ version = "0.26.0"
120
+ source = "registry+https://github.com/rust-lang/crates.io-index"
121
+ checksum = "100246c0ecf400b475341b8455a9213344569af29a3c841d29270e53102e0fcf"
122
+ dependencies = [
123
+ "heck",
124
+ "proc-macro2",
125
+ "pyo3-build-config",
126
+ "quote",
127
+ "syn",
128
+ ]
129
+
130
+ [[package]]
131
+ name = "quote"
132
+ version = "1.0.47"
133
+ source = "registry+https://github.com/rust-lang/crates.io-index"
134
+ checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
135
+ dependencies = [
136
+ "proc-macro2",
137
+ ]
138
+
139
+ [[package]]
140
+ name = "rustversion"
141
+ version = "1.0.23"
142
+ source = "registry+https://github.com/rust-lang/crates.io-index"
143
+ checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
144
+
145
+ [[package]]
146
+ name = "syn"
147
+ version = "2.0.119"
148
+ source = "registry+https://github.com/rust-lang/crates.io-index"
149
+ checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
150
+ dependencies = [
151
+ "proc-macro2",
152
+ "quote",
153
+ "unicode-ident",
154
+ ]
155
+
156
+ [[package]]
157
+ name = "target-lexicon"
158
+ version = "0.13.5"
159
+ source = "registry+https://github.com/rust-lang/crates.io-index"
160
+ checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca"
161
+
162
+ [[package]]
163
+ name = "unicode-ident"
164
+ version = "1.0.24"
165
+ source = "registry+https://github.com/rust-lang/crates.io-index"
166
+ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
167
+
168
+ [[package]]
169
+ name = "unindent"
170
+ version = "0.2.4"
171
+ source = "registry+https://github.com/rust-lang/crates.io-index"
172
+ checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
@@ -0,0 +1,14 @@
1
+ [package]
2
+ name = "hayate-accel"
3
+ version = "0.1.0"
4
+ edition = "2021"
5
+
6
+ [lib]
7
+ name = "hayate_accel"
8
+ crate-type = ["cdylib"]
9
+
10
+ [dependencies]
11
+ pyo3 = { version = "0.26", features = ["abi3-py312"] }
12
+
13
+ [profile.release]
14
+ lto = true
@@ -0,0 +1,7 @@
1
+ Metadata-Version: 2.4
2
+ Name: hayate-accel
3
+ Version: 0.1.0
4
+ Summary: Optional native accelerator for the hayate web framework (Tier 2)
5
+ Author: Yusuke Hayashi
6
+ License-Expression: MIT
7
+ Requires-Python: >=3.12
@@ -0,0 +1,14 @@
1
+ [build-system]
2
+ requires = ["maturin>=1.7,<2"]
3
+ build-backend = "maturin"
4
+
5
+ [project]
6
+ name = "hayate-accel"
7
+ version = "0.1.0"
8
+ description = "Optional native accelerator for the hayate web framework (Tier 2)"
9
+ requires-python = ">=3.12"
10
+ license = "MIT"
11
+ authors = [{ name = "Yusuke Hayashi" }]
12
+
13
+ [tool.maturin]
14
+ module-name = "hayate_accel"
@@ -0,0 +1,128 @@
1
+ //! hayate Tier 2 accelerator (DESIGN.md §14.2).
2
+ //!
3
+ //! Rules of the tier: behaviorally identical to the pure-Python path for
4
+ //! everything it accepts, and a `TypeError` for everything else so the
5
+ //! caller can fall back. Semantics live in Python; this is only speed.
6
+
7
+ use pyo3::exceptions::PyTypeError;
8
+ use pyo3::prelude::*;
9
+ use pyo3::types::{PyBool, PyDict, PyFloat, PyInt, PyList, PyString, PyTuple};
10
+
11
+ fn write_json_string(out: &mut String, value: &str) {
12
+ out.push('"');
13
+ for ch in value.chars() {
14
+ match ch {
15
+ '"' => out.push_str("\\\""),
16
+ '\\' => out.push_str("\\\\"),
17
+ '\n' => out.push_str("\\n"),
18
+ '\r' => out.push_str("\\r"),
19
+ '\t' => out.push_str("\\t"),
20
+ '\u{08}' => out.push_str("\\b"),
21
+ '\u{0c}' => out.push_str("\\f"),
22
+ c if (c as u32) < 0x20 => {
23
+ out.push_str(&format!("\\u{:04x}", c as u32));
24
+ }
25
+ c => out.push(c),
26
+ }
27
+ }
28
+ out.push('"');
29
+ }
30
+
31
+ fn write_value(out: &mut String, value: &Bound<'_, PyAny>) -> PyResult<()> {
32
+ if value.is_none() {
33
+ out.push_str("null");
34
+ return Ok(());
35
+ }
36
+ // bool first: it is a subclass of int.
37
+ if let Ok(b) = value.downcast::<PyBool>() {
38
+ out.push_str(if b.is_true() { "true" } else { "false" });
39
+ return Ok(());
40
+ }
41
+ if let Ok(s) = value.downcast::<PyString>() {
42
+ write_json_string(out, s.to_str()?);
43
+ return Ok(());
44
+ }
45
+ if value.downcast::<PyInt>().is_ok() {
46
+ match value.extract::<i64>() {
47
+ Ok(n) => {
48
+ out.push_str(&n.to_string());
49
+ return Ok(());
50
+ }
51
+ // Arbitrary-precision ints go through the stdlib fallback.
52
+ Err(_) => return Err(PyTypeError::new_err("int out of accelerator range")),
53
+ }
54
+ }
55
+ if value.downcast::<PyFloat>().is_ok() {
56
+ let f: f64 = value.extract()?;
57
+ // Rust's Display never uses exponent notation, so extreme
58
+ // magnitudes (and NaN/Infinity) go through the stdlib fallback
59
+ // to keep the emitted text identical to json.dumps.
60
+ if !f.is_finite() || f.abs() >= 1e16 || (f != 0.0 && f.abs() < 1e-4) {
61
+ return Err(PyTypeError::new_err("float outside accelerator range"));
62
+ }
63
+ if f.fract() == 0.0 {
64
+ out.push_str(&format!("{:.1}", f));
65
+ } else {
66
+ out.push_str(&format!("{}", f));
67
+ }
68
+ return Ok(());
69
+ }
70
+ if let Ok(list) = value.downcast::<PyList>() {
71
+ out.push('[');
72
+ for (index, item) in list.iter().enumerate() {
73
+ if index > 0 {
74
+ out.push(',');
75
+ }
76
+ write_value(out, &item)?;
77
+ }
78
+ out.push(']');
79
+ return Ok(());
80
+ }
81
+ if let Ok(tuple) = value.downcast::<PyTuple>() {
82
+ out.push('[');
83
+ for (index, item) in tuple.iter().enumerate() {
84
+ if index > 0 {
85
+ out.push(',');
86
+ }
87
+ write_value(out, &item)?;
88
+ }
89
+ out.push(']');
90
+ return Ok(());
91
+ }
92
+ if let Ok(dict) = value.downcast::<PyDict>() {
93
+ out.push('{');
94
+ let mut first = true;
95
+ for (key, item) in dict.iter() {
96
+ let key_str = key
97
+ .downcast::<PyString>()
98
+ .map_err(|_| PyTypeError::new_err("dict keys must be str for the accelerator"))?
99
+ .to_str()?
100
+ .to_owned();
101
+ if !first {
102
+ out.push(',');
103
+ }
104
+ first = false;
105
+ write_json_string(out, &key_str);
106
+ out.push(':');
107
+ write_value(out, &item)?;
108
+ }
109
+ out.push('}');
110
+ return Ok(());
111
+ }
112
+ Err(PyTypeError::new_err("unsupported type for the accelerator"))
113
+ }
114
+
115
+ /// Compact JSON matching `json.dumps(x, ensure_ascii=False, separators=(",", ":"))`
116
+ /// for None / bool / str / int(i64) / finite float / list / tuple / str-keyed dict.
117
+ #[pyfunction]
118
+ fn json_dumps(value: &Bound<'_, PyAny>) -> PyResult<String> {
119
+ let mut out = String::with_capacity(64);
120
+ write_value(&mut out, value)?;
121
+ Ok(out)
122
+ }
123
+
124
+ #[pymodule]
125
+ fn hayate_accel(m: &Bound<'_, PyModule>) -> PyResult<()> {
126
+ m.add_function(wrap_pyfunction!(json_dumps, m)?)?;
127
+ Ok(())
128
+ }