refactor: replace custom lens parsing with panproto-lens-dsl lens_config.rs is now a thin wrapper around panproto_lens_dsl: - load_dir() scans JSON/YAML/Nickel lens files - compile() produces CompiledLens with chain + field_transforms - No custom step parsing, expression parsing, or value conversion All panproto crates switched to path dependencies from phrom checkout for development. Will switch to crates.io versions when released. Removed panproto-expr-parser from direct deps (used transitively).
Author: Aaron Steven White
Commit
afbe1568a46e75544334e7f1375fc9964ab3c6d4Parent: f0a0bf57fd
Structural diff unavailable
These commits were pushed via plain git push, so no pre-parsed
schemas are available. Install git-remote-cospan and re-push via panproto:// to
see scope-level changes, breaking change detection, and semantic diffs.
brew install panproto/tap/git-remote-cospan6 files changed +882 -332
@@ -39,6 +39,12 @@ dependencies = [
3939 ] 4040 4141 [[package]] 42+name = "aliasable" 43+version = "0.1.3" 44+source = "registry+https://github.com/rust-lang/crates.io-index" 45+checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" 46+ 47+[[package]] 4248 name = "allocator-api2" 4349 version = "0.2.21" 4450 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -84,6 +90,12 @@ dependencies = [
8490 ] 8591 8692 [[package]] 93+name = "arraydeque" 94+version = "0.5.1" 95+source = "registry+https://github.com/rust-lang/crates.io-index" 96+checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236" 97+ 98+[[package]] 8799 name = "arrayref" 88100 version = "0.3.9" 89101 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -91,11 +103,26 @@ checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb"
91103 92104 [[package]] 93105 name = "arrayvec" 106+version = "0.5.2" 107+source = "registry+https://github.com/rust-lang/crates.io-index" 108+checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" 109+ 110+[[package]] 111+name = "arrayvec" 94112 version = "0.7.6" 95113 source = "registry+https://github.com/rust-lang/crates.io-index" 96114 checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" 97115 98116 [[package]] 117+name = "ascii-canvas" 118+version = "4.0.0" 119+source = "registry+https://github.com/rust-lang/crates.io-index" 120+checksum = "ef1e3e699d84ab1b0911a1010c5c106aa34ae89aeac103be5ce0c3859db1e891" 121+dependencies = [ 122+ "term", 123+] 124+ 125+[[package]] 99126 name = "async-compression" 100127 version = "0.4.41" 101128 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -245,6 +272,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
245272 checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" 246273 247274 [[package]] 275+name = "beef" 276+version = "0.5.2" 277+source = "registry+https://github.com/rust-lang/crates.io-index" 278+checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" 279+ 280+[[package]] 281+name = "bit-set" 282+version = "0.8.0" 283+source = "registry+https://github.com/rust-lang/crates.io-index" 284+checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" 285+dependencies = [ 286+ "bit-vec", 287+] 288+ 289+[[package]] 290+name = "bit-vec" 291+version = "0.8.0" 292+source = "registry+https://github.com/rust-lang/crates.io-index" 293+checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" 294+ 295+[[package]] 248296 name = "bitflags" 249297 version = "2.11.0" 250298 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -254,13 +302,19 @@ dependencies = [
254302 ] 255303 256304 [[package]] 305+name = "bitmaps" 306+version = "3.2.1" 307+source = "registry+https://github.com/rust-lang/crates.io-index" 308+checksum = "a1d084b0137aaa901caf9f1e8b21daa6aa24d41cd806e111335541eff9683bd6" 309+ 310+[[package]] 257311 name = "blake3" 258312 version = "1.8.4" 259313 source = "registry+https://github.com/rust-lang/crates.io-index" 260314 checksum = "4d2d5991425dfd0785aed03aedcf0b321d61975c9b5b3689c774a2610ae0b51e" 261315 dependencies = [ 262316 "arrayref", 263- "arrayvec", 317+ "arrayvec 0.7.6", 264318 "cc", 265319 "cfg-if", 266320 "constant_time_eq",
@@ -293,6 +347,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
293347 checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" 294348 295349 [[package]] 350+name = "bytemuck" 351+version = "1.25.0" 352+source = "registry+https://github.com/rust-lang/crates.io-index" 353+checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" 354+ 355+[[package]] 296356 name = "byteorder" 297357 version = "1.5.0" 298358 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -357,6 +417,33 @@ dependencies = [
357417 ] 358418 359419 [[package]] 420+name = "codespan" 421+version = "0.13.1" 422+source = "registry+https://github.com/rust-lang/crates.io-index" 423+checksum = "583f52b0658b321b25fd6b209b6c76cf058f433071297de64e5980c3d9aad937" 424+dependencies = [ 425+ "codespan-reporting", 426+ "serde", 427+] 428+ 429+[[package]] 430+name = "codespan-reporting" 431+version = "0.13.1" 432+source = "registry+https://github.com/rust-lang/crates.io-index" 433+checksum = "af491d569909a7e4dee0ad7db7f5341fef5c614d5b8ec8cf765732aba3cff681" 434+dependencies = [ 435+ "serde", 436+ "termcolor", 437+ "unicode-width 0.2.2", 438+] 439+ 440+[[package]] 441+name = "colorchoice" 442+version = "1.0.5" 443+source = "registry+https://github.com/rust-lang/crates.io-index" 444+checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" 445+ 446+[[package]] 360447 name = "combine" 361448 version = "4.6.7" 362449 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -490,6 +577,7 @@ dependencies = [
490577 "panproto-gat", 491578 "panproto-inst", 492579 "panproto-lens", 580+ "panproto-lens-dsl", 493581 "panproto-mig", 494582 "panproto-protocols", 495583 "panproto-schema",
@@ -527,7 +615,7 @@ dependencies = [
527615 "tempfile", 528616 "thiserror", 529617 "tokio", 530- "toml", 618+ "toml 0.8.23", 531619 "tower", 532620 "tower-http", 533621 "tracing",
@@ -760,6 +848,15 @@ dependencies = [
760848 ] 761849 762850 [[package]] 851+name = "ena" 852+version = "0.14.4" 853+source = "registry+https://github.com/rust-lang/crates.io-index" 854+checksum = "eabffdaee24bd1bf95c5ef7cec31260444317e72ea56c4c91750e8b7ee58d5f1" 855+dependencies = [ 856+ "log", 857+] 858+ 859+[[package]] 763860 name = "encoding_rs" 764861 version = "0.8.35" 765862 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -839,6 +936,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
839936 checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" 840937 841938 [[package]] 939+name = "fixedbitset" 940+version = "0.5.7" 941+source = "registry+https://github.com/rust-lang/crates.io-index" 942+checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" 943+ 944+[[package]] 842945 name = "flate2" 843946 version = "1.1.9" 844947 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1165,6 +1268,12 @@ dependencies = [
11651268 11661269 [[package]] 11671270 name = "heck" 1271+version = "0.4.1" 1272+source = "registry+https://github.com/rust-lang/crates.io-index" 1273+checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 1274+ 1275+[[package]] 1276+name = "heck" 11681277 version = "0.5.0" 11691278 source = "registry+https://github.com/rust-lang/crates.io-index" 11701279 checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
@@ -1460,6 +1569,15 @@ dependencies = [
14601569 ] 14611570 14621571 [[package]] 1572+name = "imbl-sized-chunks" 1573+version = "0.1.3" 1574+source = "registry+https://github.com/rust-lang/crates.io-index" 1575+checksum = "8f4241005618a62f8d57b2febd02510fb96e0137304728543dfc5fd6f052c22d" 1576+dependencies = [ 1577+ "bitmaps", 1578+] 1579+ 1580+[[package]] 14631581 name = "indexmap" 14641582 version = "2.13.0" 14651583 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1472,6 +1590,15 @@ dependencies = [
14721590 ] 14731591 14741592 [[package]] 1593+name = "indoc" 1594+version = "2.0.7" 1595+source = "registry+https://github.com/rust-lang/crates.io-index" 1596+checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706" 1597+dependencies = [ 1598+ "rustversion", 1599+] 1600+ 1601+[[package]] 14751602 name = "ipnet" 14761603 version = "2.12.0" 14771604 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1503,6 +1630,15 @@ dependencies = [
15031630 ] 15041631 15051632 [[package]] 1633+name = "itertools" 1634+version = "0.14.0" 1635+source = "registry+https://github.com/rust-lang/crates.io-index" 1636+checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" 1637+dependencies = [ 1638+ "either", 1639+] 1640+ 1641+[[package]] 15061642 name = "itoa" 15071643 version = "1.0.18" 15081644 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1531,6 +1667,15 @@ dependencies = [
15311667 ] 15321668 15331669 [[package]] 1670+name = "json_scanner" 1671+version = "0.1.0" 1672+source = "registry+https://github.com/rust-lang/crates.io-index" 1673+checksum = "fe0a2dc336065c75719cffd3c6c929e0ec4ed85b92b8248a7bbd999acb0e419c" 1674+dependencies = [ 1675+ "memchr", 1676+] 1677+ 1678+[[package]] 15341679 name = "jsonwebtoken" 15351680 version = "9.3.1" 15361681 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1546,6 +1691,47 @@ dependencies = [
15461691 ] 15471692 15481693 [[package]] 1694+name = "keccak" 1695+version = "0.1.6" 1696+source = "registry+https://github.com/rust-lang/crates.io-index" 1697+checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" 1698+dependencies = [ 1699+ "cpufeatures 0.2.17", 1700+] 1701+ 1702+[[package]] 1703+name = "lalrpop" 1704+version = "0.22.2" 1705+source = "registry+https://github.com/rust-lang/crates.io-index" 1706+checksum = "ba4ebbd48ce411c1d10fb35185f5a51a7bfa3d8b24b4e330d30c9e3a34129501" 1707+dependencies = [ 1708+ "ascii-canvas", 1709+ "bit-set", 1710+ "ena", 1711+ "itertools 0.14.0", 1712+ "lalrpop-util", 1713+ "petgraph", 1714+ "pico-args", 1715+ "regex", 1716+ "regex-syntax 0.8.10", 1717+ "sha3", 1718+ "string_cache", 1719+ "term", 1720+ "unicode-xid", 1721+ "walkdir", 1722+] 1723+ 1724+[[package]] 1725+name = "lalrpop-util" 1726+version = "0.22.2" 1727+source = "registry+https://github.com/rust-lang/crates.io-index" 1728+checksum = "b5baa5e9ff84f1aefd264e6869907646538a52147a755d494517a8007fb48733" 1729+dependencies = [ 1730+ "regex-automata 0.4.14", 1731+ "rustversion", 1732+] 1733+ 1734+[[package]] 15491735 name = "lazy_static" 15501736 version = "1.5.0" 15511737 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1623,6 +1809,12 @@ dependencies = [
16231809 ] 16241810 16251811 [[package]] 1812+name = "libyaml-rs" 1813+version = "0.3.0" 1814+source = "registry+https://github.com/rust-lang/crates.io-index" 1815+checksum = "2e126dda6f34391ab7b444f9922055facc83c07a910da3eb16f1e4d9c45dc777" 1816+ 1817+[[package]] 16261818 name = "libz-sys" 16271819 version = "1.1.25" 16281820 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1663,11 +1855,36 @@ checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
16631855 16641856 [[package]] 16651857 name = "logos" 1858+version = "0.15.1" 1859+source = "registry+https://github.com/rust-lang/crates.io-index" 1860+checksum = "ff472f899b4ec2d99161c51f60ff7075eeb3097069a36050d8037a6325eb8154" 1861+dependencies = [ 1862+ "logos-derive 0.15.1", 1863+] 1864+ 1865+[[package]] 1866+name = "logos" 16661867 version = "0.16.1" 16671868 source = "registry+https://github.com/rust-lang/crates.io-index" 16681869 checksum = "eb2c55a318a87600ea870ff8c2012148b44bf18b74fad48d0f835c38c7d07c5f" 16691870 dependencies = [ 1670- "logos-derive", 1871+ "logos-derive 0.16.1", 1872+] 1873+ 1874+[[package]] 1875+name = "logos-codegen" 1876+version = "0.15.1" 1877+source = "registry+https://github.com/rust-lang/crates.io-index" 1878+checksum = "192a3a2b90b0c05b27a0b2c43eecdb7c415e29243acc3f89cc8247a5b693045c" 1879+dependencies = [ 1880+ "beef", 1881+ "fnv", 1882+ "lazy_static", 1883+ "proc-macro2", 1884+ "quote", 1885+ "regex-syntax 0.8.10", 1886+ "rustc_version", 1887+ "syn", 16711888 ] 16721889 16731890 [[package]]
@@ -1686,11 +1903,20 @@ dependencies = [
16861903 16871904 [[package]] 16881905 name = "logos-derive" 1906+version = "0.15.1" 1907+source = "registry+https://github.com/rust-lang/crates.io-index" 1908+checksum = "605d9697bcd5ef3a42d38efc51541aa3d6a4a25f7ab6d1ed0da5ac632a26b470" 1909+dependencies = [ 1910+ "logos-codegen 0.15.1", 1911+] 1912+ 1913+[[package]] 1914+name = "logos-derive" 16891915 version = "0.16.1" 16901916 source = "registry+https://github.com/rust-lang/crates.io-index" 16911917 checksum = "52d3a9855747c17eaf4383823f135220716ab49bea5fbea7dd42cc9a92f8aa31" 16921918 dependencies = [ 1693- "logos-codegen", 1919+ "logos-codegen 0.16.1", 16941920 ] 16951921 16961922 [[package]]
@@ -1700,6 +1926,68 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
17001926 checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" 17011927 17021928 [[package]] 1929+name = "malachite" 1930+version = "0.6.1" 1931+source = "registry+https://github.com/rust-lang/crates.io-index" 1932+checksum = "ec410515e231332b14cd986a475d1c3323bcfa4c7efc038bfa1d5b410b1c57e4" 1933+dependencies = [ 1934+ "malachite-base", 1935+ "malachite-float", 1936+ "malachite-nz", 1937+ "malachite-q", 1938+] 1939+ 1940+[[package]] 1941+name = "malachite-base" 1942+version = "0.6.1" 1943+source = "registry+https://github.com/rust-lang/crates.io-index" 1944+checksum = "c738d3789301e957a8f7519318fcbb1b92bb95863b28f6938ae5a05be6259f34" 1945+dependencies = [ 1946+ "hashbrown 0.15.5", 1947+ "itertools 0.14.0", 1948+ "libm", 1949+ "ryu", 1950+] 1951+ 1952+[[package]] 1953+name = "malachite-float" 1954+version = "0.6.1" 1955+source = "registry+https://github.com/rust-lang/crates.io-index" 1956+checksum = "9446a966be7f1708c10badd6690d3094b5ad62d3accdcf2154740656d7650cfa" 1957+dependencies = [ 1958+ "itertools 0.14.0", 1959+ "malachite-base", 1960+ "malachite-nz", 1961+ "malachite-q", 1962+ "serde", 1963+] 1964+ 1965+[[package]] 1966+name = "malachite-nz" 1967+version = "0.6.1" 1968+source = "registry+https://github.com/rust-lang/crates.io-index" 1969+checksum = "1707c9a1fa36ce21749b35972bfad17bbf34cf5a7c96897c0491da321e387d3b" 1970+dependencies = [ 1971+ "itertools 0.14.0", 1972+ "libm", 1973+ "malachite-base", 1974+ "serde", 1975+ "wide", 1976+] 1977+ 1978+[[package]] 1979+name = "malachite-q" 1980+version = "0.6.1" 1981+source = "registry+https://github.com/rust-lang/crates.io-index" 1982+checksum = "d764801aa4e96bbb69b389dcd03b50075345131cd63ca2e380bca71cc37a3675" 1983+dependencies = [ 1984+ "itertools 0.14.0", 1985+ "malachite-base", 1986+ "malachite-nz", 1987+ "serde", 1988+] 1989+ 1990+[[package]] 17031991 name = "matchers" 17041992 version = "0.2.0" 17051993 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1851,6 +2139,108 @@ dependencies = [
18512139 ] 18522140 18532141 [[package]] 2142+name = "new_debug_unreachable" 2143+version = "1.0.6" 2144+source = "registry+https://github.com/rust-lang/crates.io-index" 2145+checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" 2146+ 2147+[[package]] 2148+name = "nickel-lang" 2149+version = "2.0.0" 2150+source = "registry+https://github.com/rust-lang/crates.io-index" 2151+checksum = "ec629a17e21b7e192dfc715a9567fb4f773a6d0c92424f0ec659c6633f31b087" 2152+dependencies = [ 2153+ "codespan-reporting", 2154+ "indexmap", 2155+ "malachite", 2156+ "nickel-lang-core", 2157+ "nickel-lang-vector", 2158+ "serde", 2159+ "serde_json", 2160+ "serde_yaml", 2161+ "toml 0.9.12+spec-1.1.0", 2162+] 2163+ 2164+[[package]] 2165+name = "nickel-lang-core" 2166+version = "0.16.1" 2167+source = "registry+https://github.com/rust-lang/crates.io-index" 2168+checksum = "51647f09e6e385c140226867c62292f23c31241ee2b4986f3f71a40d48e88a60" 2169+dependencies = [ 2170+ "base64", 2171+ "bumpalo", 2172+ "codespan", 2173+ "codespan-reporting", 2174+ "colorchoice", 2175+ "indexmap", 2176+ "indoc", 2177+ "json_scanner", 2178+ "lalrpop", 2179+ "lalrpop-util", 2180+ "logos 0.15.1", 2181+ "malachite", 2182+ "malachite-q", 2183+ "md-5", 2184+ "nickel-lang-parser", 2185+ "nickel-lang-vector", 2186+ "once_cell", 2187+ "ouroboros", 2188+ "paste", 2189+ "pretty", 2190+ "regex", 2191+ "saphyr-parser", 2192+ "serde", 2193+ "serde_json", 2194+ "serde_yaml", 2195+ "sha-1", 2196+ "sha2", 2197+ "simple-counter", 2198+ "smallvec 1.15.1", 2199+ "strip-ansi-escapes", 2200+ "strsim", 2201+ "toml 0.9.12+spec-1.1.0", 2202+ "toml_edit 0.23.10+spec-1.0.0", 2203+ "typed-arena", 2204+ "unicode-segmentation", 2205+] 2206+ 2207+[[package]] 2208+name = "nickel-lang-parser" 2209+version = "0.1.1" 2210+source = "registry+https://github.com/rust-lang/crates.io-index" 2211+checksum = "20d8810705f1a243b1996c83fe9f173d8fb33f1cc97ea5ff7486cc6ef8981f81" 2212+dependencies = [ 2213+ "bumpalo", 2214+ "codespan", 2215+ "codespan-reporting", 2216+ "indexmap", 2217+ "lalrpop", 2218+ "lalrpop-util", 2219+ "logos 0.15.1", 2220+ "malachite", 2221+ "nickel-lang-vector", 2222+ "ouroboros", 2223+ "pretty", 2224+ "regex", 2225+ "saphyr-parser", 2226+ "serde", 2227+ "serde_json", 2228+ "simple-counter", 2229+ "toml_edit 0.23.10+spec-1.0.0", 2230+ "typed-arena", 2231+] 2232+ 2233+[[package]] 2234+name = "nickel-lang-vector" 2235+version = "0.1.0" 2236+source = "registry+https://github.com/rust-lang/crates.io-index" 2237+checksum = "870c323d81061fc47db4aa7346f6f3492f3e4bb8bd5dd8b7c85ac9d0c9709f0c" 2238+dependencies = [ 2239+ "imbl-sized-chunks", 2240+ "serde", 2241+] 2242+ 2243+[[package]] 18542244 name = "nu-ansi-term" 18552245 version = "0.50.3" 18562246 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1993,6 +2383,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
19932383 checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" 19942384 19952385 [[package]] 2386+name = "ouroboros" 2387+version = "0.18.5" 2388+source = "registry+https://github.com/rust-lang/crates.io-index" 2389+checksum = "1e0f050db9c44b97a94723127e6be766ac5c340c48f2c4bb3ffa11713744be59" 2390+dependencies = [ 2391+ "aliasable", 2392+ "ouroboros_macro", 2393+ "static_assertions", 2394+] 2395+ 2396+[[package]] 2397+name = "ouroboros_macro" 2398+version = "0.18.5" 2399+source = "registry+https://github.com/rust-lang/crates.io-index" 2400+checksum = "3c7028bdd3d43083f6d8d4d5187680d0d3560d54df4cc9d752005268b41e64d0" 2401+dependencies = [ 2402+ "heck 0.4.1", 2403+ "proc-macro2", 2404+ "proc-macro2-diagnostics", 2405+ "quote", 2406+ "syn", 2407+] 2408+ 2409+[[package]] 19962410 name = "owo-colors" 19972411 version = "4.3.0" 19982412 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2012,8 +2426,7 @@ dependencies = [
20122426 20132427 [[package]] 20142428 name = "panproto-check" 2015-version = "0.23.0" 2016-source = "git+https://github.com/panproto/panproto.git?tag=v0.23.0#be3c299556210beccc02113c870734cbfe6bde4e" 2429+version = "0.24.0" 20172430 dependencies = [ 20182431 "panproto-gat", 20192432 "panproto-lens",
@@ -2027,8 +2440,7 @@ dependencies = [
20272440 20282441 [[package]] 20292442 name = "panproto-core" 2030-version = "0.23.0" 2031-source = "git+https://github.com/panproto/panproto.git?tag=v0.23.0#be3c299556210beccc02113c870734cbfe6bde4e" 2443+version = "0.24.0" 20322444 dependencies = [ 20332445 "panproto-check", 20342446 "panproto-gat",
@@ -2043,8 +2455,7 @@ dependencies = [
20432455 20442456 [[package]] 20452457 name = "panproto-expr" 2046-version = "0.23.0" 2047-source = "git+https://github.com/panproto/panproto.git?tag=v0.23.0#be3c299556210beccc02113c870734cbfe6bde4e" 2458+version = "0.24.0" 20482459 dependencies = [ 20492460 "rustc-hash", 20502461 "serde",
@@ -2053,18 +2464,16 @@ dependencies = [
20532464 20542465 [[package]] 20552466 name = "panproto-expr-parser" 2056-version = "0.23.0" 2057-source = "git+https://github.com/panproto/panproto.git?tag=v0.23.0#be3c299556210beccc02113c870734cbfe6bde4e" 2467+version = "0.24.0" 20582468 dependencies = [ 20592469 "chumsky", 2060- "logos", 2470+ "logos 0.16.1", 20612471 "panproto-expr", 20622472 ] 20632473 20642474 [[package]] 20652475 name = "panproto-gat" 2066-version = "0.23.0" 2067-source = "git+https://github.com/panproto/panproto.git?tag=v0.23.0#be3c299556210beccc02113c870734cbfe6bde4e" 2476+version = "0.24.0" 20682477 dependencies = [ 20692478 "panproto-expr", 20702479 "rustc-hash",
@@ -2074,8 +2483,7 @@ dependencies = [
20742483 20752484 [[package]] 20762485 name = "panproto-git" 2077-version = "0.23.0" 2078-source = "git+https://github.com/panproto/panproto.git?tag=v0.23.0#be3c299556210beccc02113c870734cbfe6bde4e" 2486+version = "0.24.0" 20792487 dependencies = [ 20802488 "git2", 20812489 "miette",
@@ -2092,20 +2500,18 @@ dependencies = [
20922500 20932501 [[package]] 20942502 name = "panproto-grammars" 2095-version = "0.23.0" 2096-source = "git+https://github.com/panproto/panproto.git?tag=v0.23.0#be3c299556210beccc02113c870734cbfe6bde4e" 2503+version = "0.24.0" 20972504 dependencies = [ 20982505 "cc", 20992506 "serde", 2100- "toml", 2507+ "toml 0.8.23", 21012508 "tree-sitter", 21022509 "tree-sitter-language", 21032510 ] 21042511 21052512 [[package]] 21062513 name = "panproto-inst" 2107-version = "0.23.0" 2108-source = "git+https://github.com/panproto/panproto.git?tag=v0.23.0#be3c299556210beccc02113c870734cbfe6bde4e" 2514+version = "0.24.0" 21092515 dependencies = [ 21102516 "bumpalo", 21112517 "panproto-expr",
@@ -2120,8 +2526,7 @@ dependencies = [
21202526 21212527 [[package]] 21222528 name = "panproto-io" 2123-version = "0.23.0" 2124-source = "git+https://github.com/panproto/panproto.git?tag=v0.23.0#be3c299556210beccc02113c870734cbfe6bde4e" 2529+version = "0.24.0" 21252530 dependencies = [ 21262531 "bumpalo", 21272532 "memchr",
@@ -2143,8 +2548,7 @@ dependencies = [
21432548 21442549 [[package]] 21452550 name = "panproto-lens" 2146-version = "0.23.0" 2147-source = "git+https://github.com/panproto/panproto.git?tag=v0.23.0#be3c299556210beccc02113c870734cbfe6bde4e" 2551+version = "0.24.0" 21482552 dependencies = [ 21492553 "panproto-expr", 21502554 "panproto-gat",
@@ -2159,9 +2563,26 @@ dependencies = [
21592563 ] 21602564 21612565 [[package]] 2566+name = "panproto-lens-dsl" 2567+version = "0.24.0" 2568+dependencies = [ 2569+ "miette", 2570+ "nickel-lang", 2571+ "panproto-expr", 2572+ "panproto-expr-parser", 2573+ "panproto-gat", 2574+ "panproto-inst", 2575+ "panproto-lens", 2576+ "serde", 2577+ "serde_json", 2578+ "tempfile", 2579+ "thiserror", 2580+ "yaml_serde", 2581+] 2582+ 2583+[[package]] 21622584 name = "panproto-mig" 2163-version = "0.23.0" 2164-source = "git+https://github.com/panproto/panproto.git?tag=v0.23.0#be3c299556210beccc02113c870734cbfe6bde4e" 2585+version = "0.24.0" 21652586 dependencies = [ 21662587 "panproto-expr", 21672588 "panproto-gat",
@@ -2174,8 +2595,7 @@ dependencies = [
21742595 21752596 [[package]] 21762597 name = "panproto-parse" 2177-version = "0.23.0" 2178-source = "git+https://github.com/panproto/panproto.git?tag=v0.23.0#be3c299556210beccc02113c870734cbfe6bde4e" 2598+version = "0.24.0" 21792599 dependencies = [ 21802600 "memchr", 21812601 "miette",
@@ -2193,8 +2613,7 @@ dependencies = [
21932613 21942614 [[package]] 21952615 name = "panproto-project" 2196-version = "0.23.0" 2197-source = "git+https://github.com/panproto/panproto.git?tag=v0.23.0#be3c299556210beccc02113c870734cbfe6bde4e" 2616+version = "0.24.0" 21982617 dependencies = [ 21992618 "blake3", 22002619 "globset",
@@ -2208,13 +2627,12 @@ dependencies = [
22082627 "serde_json", 22092628 "smallvec 2.0.0-alpha.12", 22102629 "thiserror", 2211- "toml", 2630+ "toml 0.8.23", 22122631 ] 22132632 22142633 [[package]] 22152634 name = "panproto-protocols" 2216-version = "0.23.0" 2217-source = "git+https://github.com/panproto/panproto.git?tag=v0.23.0#be3c299556210beccc02113c870734cbfe6bde4e" 2635+version = "0.24.0" 22182636 dependencies = [ 22192637 "blake3", 22202638 "panproto-gat",
@@ -2228,8 +2646,7 @@ dependencies = [
22282646 22292647 [[package]] 22302648 name = "panproto-schema" 2231-version = "0.23.0" 2232-source = "git+https://github.com/panproto/panproto.git?tag=v0.23.0#be3c299556210beccc02113c870734cbfe6bde4e" 2649+version = "0.24.0" 22332650 dependencies = [ 22342651 "panproto-expr", 22352652 "panproto-gat",
@@ -2241,8 +2658,7 @@ dependencies = [
22412658 22422659 [[package]] 22432660 name = "panproto-vcs" 2244-version = "0.23.0" 2245-source = "git+https://github.com/panproto/panproto.git?tag=v0.23.0#be3c299556210beccc02113c870734cbfe6bde4e" 2661+version = "0.24.0" 22462662 dependencies = [ 22472663 "blake3", 22482664 "panproto-check",
@@ -2262,8 +2678,7 @@ dependencies = [
22622678 22632679 [[package]] 22642680 name = "panproto-xrpc" 2265-version = "0.23.0" 2266-source = "git+https://github.com/panproto/panproto.git?tag=v0.23.0#be3c299556210beccc02113c870734cbfe6bde4e" 2681+version = "0.24.0" 22672682 dependencies = [ 22682683 "hex", 22692684 "miette",
@@ -2307,6 +2722,12 @@ dependencies = [
23072722 ] 23082723 23092724 [[package]] 2725+name = "paste" 2726+version = "1.0.15" 2727+source = "registry+https://github.com/rust-lang/crates.io-index" 2728+checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" 2729+ 2730+[[package]] 23102731 name = "pem" 23112732 version = "3.0.6" 23122733 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2332,6 +2753,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
23322753 checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" 23332754 23342755 [[package]] 2756+name = "petgraph" 2757+version = "0.7.1" 2758+source = "registry+https://github.com/rust-lang/crates.io-index" 2759+checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" 2760+dependencies = [ 2761+ "fixedbitset", 2762+ "indexmap", 2763+] 2764+ 2765+[[package]] 2766+name = "phf_shared" 2767+version = "0.11.3" 2768+source = "registry+https://github.com/rust-lang/crates.io-index" 2769+checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" 2770+dependencies = [ 2771+ "siphasher", 2772+] 2773+ 2774+[[package]] 2775+name = "pico-args" 2776+version = "0.5.0" 2777+source = "registry+https://github.com/rust-lang/crates.io-index" 2778+checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" 2779+ 2780+[[package]] 23352781 name = "pin-project-lite" 23362782 version = "0.2.17" 23372783 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2401,6 +2847,12 @@ dependencies = [
24012847 ] 24022848 24032849 [[package]] 2850+name = "precomputed-hash" 2851+version = "0.1.1" 2852+source = "registry+https://github.com/rust-lang/crates.io-index" 2853+checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" 2854+ 2855+[[package]] 24042856 name = "predicates" 24052857 version = "3.1.4" 24062858 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2427,6 +2879,17 @@ dependencies = [
24272879 ] 24282880 24292881 [[package]] 2882+name = "pretty" 2883+version = "0.12.5" 2884+source = "registry+https://github.com/rust-lang/crates.io-index" 2885+checksum = "0d22152487193190344590e4f30e219cf3fe140d9e7a3fdb683d82aa2c5f4156" 2886+dependencies = [ 2887+ "arrayvec 0.5.2", 2888+ "typed-arena", 2889+ "unicode-width 0.2.2", 2890+] 2891+ 2892+[[package]] 24302893 name = "prettyplease" 24312894 version = "0.2.37" 24322895 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2455,6 +2918,19 @@ dependencies = [
24552918 ] 24562919 24572920 [[package]] 2921+name = "proc-macro2-diagnostics" 2922+version = "0.10.1" 2923+source = "registry+https://github.com/rust-lang/crates.io-index" 2924+checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" 2925+dependencies = [ 2926+ "proc-macro2", 2927+ "quote", 2928+ "syn", 2929+ "version_check", 2930+ "yansi", 2931+] 2932+ 2933+[[package]] 24582934 name = "psm" 24592935 version = "0.1.30" 24602936 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2638,7 +3114,7 @@ dependencies = [
26383114 "bytes", 26393115 "combine", 26403116 "futures-util", 2641- "itertools", 3117+ "itertools 0.13.0", 26423118 "itoa", 26433119 "num-bigint", 26443120 "percent-encoding",
@@ -2866,6 +3342,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
28663342 checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" 28673343 28683344 [[package]] 3345+name = "rustc_version" 3346+version = "0.4.1" 3347+source = "registry+https://github.com/rust-lang/crates.io-index" 3348+checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" 3349+dependencies = [ 3350+ "semver", 3351+] 3352+ 3353+[[package]] 28693354 name = "rustix" 28703355 version = "1.1.4" 28713356 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2926,6 +3411,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
29263411 checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" 29273412 29283413 [[package]] 3414+name = "safe_arch" 3415+version = "0.7.4" 3416+source = "registry+https://github.com/rust-lang/crates.io-index" 3417+checksum = "96b02de82ddbe1b636e6170c21be622223aea188ef2e139be0a5b219ec215323" 3418+dependencies = [ 3419+ "bytemuck", 3420+] 3421+ 3422+[[package]] 3423+name = "same-file" 3424+version = "1.0.6" 3425+source = "registry+https://github.com/rust-lang/crates.io-index" 3426+checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 3427+dependencies = [ 3428+ "winapi-util", 3429+] 3430+ 3431+[[package]] 3432+name = "saphyr-parser" 3433+version = "0.0.6" 3434+source = "registry+https://github.com/rust-lang/crates.io-index" 3435+checksum = "4fb771b59f6b1985d1406325ec28f97cfb14256abcec4fdfb37b36a1766d6af7" 3436+dependencies = [ 3437+ "arraydeque", 3438+ "hashlink", 3439+] 3440+ 3441+[[package]] 29293442 name = "schannel" 29303443 version = "0.1.29" 29313444 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3049,6 +3562,15 @@ dependencies = [
30493562 ] 30503563 30513564 [[package]] 3565+name = "serde_spanned" 3566+version = "1.1.1" 3567+source = "registry+https://github.com/rust-lang/crates.io-index" 3568+checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" 3569+dependencies = [ 3570+ "serde_core", 3571+] 3572+ 3573+[[package]] 30523574 name = "serde_urlencoded" 30533575 version = "0.7.1" 30543576 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3061,6 +3583,19 @@ dependencies = [
30613583 ] 30623584 30633585 [[package]] 3586+name = "serde_yaml" 3587+version = "0.9.34+deprecated" 3588+source = "registry+https://github.com/rust-lang/crates.io-index" 3589+checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" 3590+dependencies = [ 3591+ "indexmap", 3592+ "itoa", 3593+ "ryu", 3594+ "serde", 3595+ "unsafe-libyaml", 3596+] 3597+ 3598+[[package]] 30643599 name = "serdect" 30653600 version = "0.2.0" 30663601 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3071,6 +3606,17 @@ dependencies = [
30713606 ] 30723607 30733608 [[package]] 3609+name = "sha-1" 3610+version = "0.10.1" 3611+source = "registry+https://github.com/rust-lang/crates.io-index" 3612+checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" 3613+dependencies = [ 3614+ "cfg-if", 3615+ "cpufeatures 0.2.17", 3616+ "digest", 3617+] 3618+ 3619+[[package]] 30743620 name = "sha1" 30753621 version = "0.10.6" 30763622 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3099,6 +3645,16 @@ dependencies = [
30993645 ] 31003646 31013647 [[package]] 3648+name = "sha3" 3649+version = "0.10.8" 3650+source = "registry+https://github.com/rust-lang/crates.io-index" 3651+checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" 3652+dependencies = [ 3653+ "digest", 3654+ "keccak", 3655+] 3656+ 3657+[[package]] 31023658 name = "sharded-slab" 31033659 version = "0.1.7" 31043660 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3161,6 +3717,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
31613717 checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" 31623718 31633719 [[package]] 3720+name = "simple-counter" 3721+version = "0.1.0" 3722+source = "registry+https://github.com/rust-lang/crates.io-index" 3723+checksum = "4bb57743b52ea059937169c0061d70298fe2df1d2c988b44caae79dd979d9b49" 3724+ 3725+[[package]] 31643726 name = "simple_asn1" 31653727 version = "0.6.4" 31663728 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3173,6 +3735,12 @@ dependencies = [
31733735 ] 31743736 31753737 [[package]] 3738+name = "siphasher" 3739+version = "1.0.2" 3740+source = "registry+https://github.com/rust-lang/crates.io-index" 3741+checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" 3742+ 3743+[[package]] 31763744 name = "slab" 31773745 version = "0.4.12" 31783746 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3304,7 +3872,7 @@ checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b"
33043872 dependencies = [ 33053873 "dotenvy", 33063874 "either", 3307- "heck", 3875+ "heck 0.5.0", 33083876 "hex", 33093877 "once_cell", 33103878 "proc-macro2",
@@ -3447,12 +4015,30 @@ dependencies = [
34474015 ] 34484016 34494017 [[package]] 4018+name = "static_assertions" 4019+version = "1.1.0" 4020+source = "registry+https://github.com/rust-lang/crates.io-index" 4021+checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 4022+ 4023+[[package]] 34504024 name = "streaming-iterator" 34514025 version = "0.1.9" 34524026 source = "registry+https://github.com/rust-lang/crates.io-index" 34534027 checksum = "2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520" 34544028 34554029 [[package]] 4030+name = "string_cache" 4031+version = "0.8.9" 4032+source = "registry+https://github.com/rust-lang/crates.io-index" 4033+checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" 4034+dependencies = [ 4035+ "new_debug_unreachable", 4036+ "parking_lot", 4037+ "phf_shared", 4038+ "precomputed-hash", 4039+] 4040+ 4041+[[package]] 34564042 name = "stringprep" 34574043 version = "0.1.5" 34584044 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3464,6 +4050,21 @@ dependencies = [
34644050 ] 34654051 34664052 [[package]] 4053+name = "strip-ansi-escapes" 4054+version = "0.2.1" 4055+source = "registry+https://github.com/rust-lang/crates.io-index" 4056+checksum = "2a8f8038e7e7969abb3f1b7c2a811225e9296da208539e0f79c5251d6cac0025" 4057+dependencies = [ 4058+ "vte", 4059+] 4060+ 4061+[[package]] 4062+name = "strsim" 4063+version = "0.11.1" 4064+source = "registry+https://github.com/rust-lang/crates.io-index" 4065+checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 4066+ 4067+[[package]] 34674068 name = "subtle" 34684069 version = "2.6.1" 34694070 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3562,6 +4163,24 @@ dependencies = [
35624163 ] 35634164 35644165 [[package]] 4166+name = "term" 4167+version = "1.2.1" 4168+source = "registry+https://github.com/rust-lang/crates.io-index" 4169+checksum = "d8c27177b12a6399ffc08b98f76f7c9a1f4fe9fc967c784c5a071fa8d93cf7e1" 4170+dependencies = [ 4171+ "windows-sys 0.61.2", 4172+] 4173+ 4174+[[package]] 4175+name = "termcolor" 4176+version = "1.4.1" 4177+source = "registry+https://github.com/rust-lang/crates.io-index" 4178+checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" 4179+dependencies = [ 4180+ "winapi-util", 4181+] 4182+ 4183+[[package]] 35654184 name = "terminal_size" 35664185 version = "0.4.4" 35674186 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3774,9 +4393,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
37744393 checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" 37754394 dependencies = [ 37764395 "serde", 3777- "serde_spanned", 3778- "toml_datetime", 3779- "toml_edit", 4396+ "serde_spanned 0.6.9", 4397+ "toml_datetime 0.6.11", 4398+ "toml_edit 0.22.27", 4399+] 4400+ 4401+[[package]] 4402+name = "toml" 4403+version = "0.9.12+spec-1.1.0" 4404+source = "registry+https://github.com/rust-lang/crates.io-index" 4405+checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" 4406+dependencies = [ 4407+ "indexmap", 4408+ "serde_core", 4409+ "serde_spanned 1.1.1", 4410+ "toml_datetime 0.7.5+spec-1.1.0", 4411+ "toml_parser", 4412+ "toml_writer", 4413+ "winnow 0.7.15", 37804414 ] 37814415 37824416 [[package]]
@@ -3789,6 +4423,15 @@ dependencies = [
37894423 ] 37904424 37914425 [[package]] 4426+name = "toml_datetime" 4427+version = "0.7.5+spec-1.1.0" 4428+source = "registry+https://github.com/rust-lang/crates.io-index" 4429+checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" 4430+dependencies = [ 4431+ "serde_core", 4432+] 4433+ 4434+[[package]] 37924435 name = "toml_edit" 37934436 version = "0.22.27" 37944437 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3796,10 +4439,32 @@ checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
37964439 dependencies = [ 37974440 "indexmap", 37984441 "serde", 3799- "serde_spanned", 3800- "toml_datetime", 4442+ "serde_spanned 0.6.9", 4443+ "toml_datetime 0.6.11", 38014444 "toml_write", 3802- "winnow", 4445+ "winnow 0.7.15", 4446+] 4447+ 4448+[[package]] 4449+name = "toml_edit" 4450+version = "0.23.10+spec-1.0.0" 4451+source = "registry+https://github.com/rust-lang/crates.io-index" 4452+checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" 4453+dependencies = [ 4454+ "indexmap", 4455+ "toml_datetime 0.7.5+spec-1.1.0", 4456+ "toml_parser", 4457+ "toml_writer", 4458+ "winnow 0.7.15", 4459+] 4460+ 4461+[[package]] 4462+name = "toml_parser" 4463+version = "1.1.1+spec-1.1.0" 4464+source = "registry+https://github.com/rust-lang/crates.io-index" 4465+checksum = "39ca317ebc49f06bd748bfba29533eac9485569dc9bf80b849024b025e814fb9" 4466+dependencies = [ 4467+ "winnow 1.0.1", 38034468 ] 38044469 38054470 [[package]]
@@ -3809,6 +4474,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
38094474 checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" 38104475 38114476 [[package]] 4477+name = "toml_writer" 4478+version = "1.1.1+spec-1.1.0" 4479+source = "registry+https://github.com/rust-lang/crates.io-index" 4480+checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" 4481+ 4482+[[package]] 38124483 name = "tower" 38134484 version = "0.5.3" 38144485 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3980,6 +4651,12 @@ dependencies = [
39804651 ] 39814652 39824653 [[package]] 4654+name = "typed-arena" 4655+version = "2.0.2" 4656+source = "registry+https://github.com/rust-lang/crates.io-index" 4657+checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" 4658+ 4659+[[package]] 39834660 name = "typenum" 39844661 version = "1.19.0" 39854662 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4049,6 +4726,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
40494726 checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" 40504727 40514728 [[package]] 4729+name = "unsafe-libyaml" 4730+version = "0.2.11" 4731+source = "registry+https://github.com/rust-lang/crates.io-index" 4732+checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" 4733+ 4734+[[package]] 40524735 name = "untrusted" 40534736 version = "0.9.0" 40544737 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4126,6 +4809,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
41264809 checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 41274810 41284811 [[package]] 4812+name = "vte" 4813+version = "0.14.1" 4814+source = "registry+https://github.com/rust-lang/crates.io-index" 4815+checksum = "231fdcd7ef3037e8330d8e17e61011a2c244126acc0a982f4040ac3f9f0bc077" 4816+dependencies = [ 4817+ "memchr", 4818+] 4819+ 4820+[[package]] 4821+name = "walkdir" 4822+version = "2.5.0" 4823+source = "registry+https://github.com/rust-lang/crates.io-index" 4824+checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" 4825+dependencies = [ 4826+ "same-file", 4827+ "winapi-util", 4828+] 4829+ 4830+[[package]] 41294831 name = "want" 41304832 version = "0.3.1" 41314833 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4302,6 +5004,25 @@ dependencies = [
43025004 ] 43035005 43045006 [[package]] 5007+name = "wide" 5008+version = "0.7.33" 5009+source = "registry+https://github.com/rust-lang/crates.io-index" 5010+checksum = "0ce5da8ecb62bcd8ec8b7ea19f69a51275e91299be594ea5cc6ef7819e16cd03" 5011+dependencies = [ 5012+ "bytemuck", 5013+ "safe_arch", 5014+] 5015+ 5016+[[package]] 5017+name = "winapi-util" 5018+version = "0.1.11" 5019+source = "registry+https://github.com/rust-lang/crates.io-index" 5020+checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" 5021+dependencies = [ 5022+ "windows-sys 0.61.2", 5023+] 5024+ 5025+[[package]] 43055026 name = "windows-core" 43065027 version = "0.62.2" 43075028 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4612,6 +5333,12 @@ dependencies = [
46125333 ] 46135334 46145335 [[package]] 5336+name = "winnow" 5337+version = "1.0.1" 5338+source = "registry+https://github.com/rust-lang/crates.io-index" 5339+checksum = "09dac053f1cd375980747450bfc7250c264eaae0583872e845c0c7cd578872b5" 5340+ 5341+[[package]] 46155342 name = "wit-bindgen" 46165343 version = "0.51.0" 46175344 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4627,7 +5354,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
46275354 checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" 46285355 dependencies = [ 46295356 "anyhow", 4630- "heck", 5357+ "heck 0.5.0", 46315358 "wit-parser", 46325359 ] 46335360
@@ -4638,7 +5365,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
46385365 checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" 46395366 dependencies = [ 46405367 "anyhow", 4641- "heck", 5368+ "heck 0.5.0", 46425369 "indexmap", 46435370 "prettyplease", 46445371 "syn",
@@ -4706,6 +5433,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
47065433 checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" 47075434 47085435 [[package]] 5436+name = "yaml_serde" 5437+version = "0.10.4" 5438+source = "registry+https://github.com/rust-lang/crates.io-index" 5439+checksum = "08c7c1b1a6a7c8a6b2741a6c21a4f8918e51899b111cfa08d1288202656e3975" 5440+dependencies = [ 5441+ "indexmap", 5442+ "itoa", 5443+ "libyaml-rs", 5444+ "ryu", 5445+ "serde", 5446+] 5447+ 5448+[[package]] 5449+name = "yansi" 5450+version = "1.0.1" 5451+source = "registry+https://github.com/rust-lang/crates.io-index" 5452+checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" 5453+ 5454+[[package]] 47095455 name = "yoke" 47105456 version = "0.8.1" 47115457 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -13,25 +13,25 @@ license = "AGPL-3.0-or-later"
1313 repository = "https://github.com/cospan-dev/cospan" 1414 1515 [workspace.dependencies] 16-# panproto — all from git because panproto-grammars needs vendored C sources 17-# (too large for crates.io). All crates must come from the same source to avoid 18-# type mismatches between git and crates.io versions of panproto-schema etc. 19-panproto-core = { git = "https://github.com/panproto/panproto.git", tag = "v0.23.0" } 20-panproto-vcs = { git = "https://github.com/panproto/panproto.git", tag = "v0.23.0" } 21-panproto-schema = { git = "https://github.com/panproto/panproto.git", tag = "v0.23.0" } 22-panproto-check = { git = "https://github.com/panproto/panproto.git", tag = "v0.23.0" } 23-panproto-lens = { git = "https://github.com/panproto/panproto.git", tag = "v0.23.0" } 24-panproto-protocols = { git = "https://github.com/panproto/panproto.git", tag = "v0.23.0" } 25-panproto-io = { git = "https://github.com/panproto/panproto.git", tag = "v0.23.0" } 26-panproto-inst = { git = "https://github.com/panproto/panproto.git", tag = "v0.23.0" } 27-panproto-gat = { git = "https://github.com/panproto/panproto.git", tag = "v0.23.0" } 28-panproto-mig = { git = "https://github.com/panproto/panproto.git", tag = "v0.23.0" } 29-panproto-expr = { git = "https://github.com/panproto/panproto.git", tag = "v0.23.0" } 30-panproto-expr-parser = { git = "https://github.com/panproto/panproto.git", tag = "v0.23.0" } 31-panproto-xrpc = { git = "https://github.com/panproto/panproto.git", tag = "v0.23.0" } 32-panproto-parse = { git = "https://github.com/panproto/panproto.git", tag = "v0.23.0", features = ["group-all"] } 33-panproto-git = { git = "https://github.com/panproto/panproto.git", tag = "v0.23.0" } 34-panproto-project = { git = "https://github.com/panproto/panproto.git", tag = "v0.23.0" } 16+# panproto — path dependencies to local phrom checkout for development. 17+# Switch to git tags or crates.io versions for release builds. 18+panproto-core = { path = "/Users/awhite48/Projects/phrom/crates/panproto-core" } 19+panproto-vcs = { path = "/Users/awhite48/Projects/phrom/crates/panproto-vcs" } 20+panproto-schema = { path = "/Users/awhite48/Projects/phrom/crates/panproto-schema" } 21+panproto-check = { path = "/Users/awhite48/Projects/phrom/crates/panproto-check" } 22+panproto-lens = { path = "/Users/awhite48/Projects/phrom/crates/panproto-lens" } 23+panproto-lens-dsl = { path = "/Users/awhite48/Projects/phrom/crates/panproto-lens-dsl" } 24+panproto-protocols = { path = "/Users/awhite48/Projects/phrom/crates/panproto-protocols" } 25+panproto-io = { path = "/Users/awhite48/Projects/phrom/crates/panproto-io" } 26+panproto-inst = { path = "/Users/awhite48/Projects/phrom/crates/panproto-inst" } 27+panproto-gat = { path = "/Users/awhite48/Projects/phrom/crates/panproto-gat" } 28+panproto-mig = { path = "/Users/awhite48/Projects/phrom/crates/panproto-mig" } 29+panproto-expr = { path = "/Users/awhite48/Projects/phrom/crates/panproto-expr" } 30+panproto-expr-parser = { path = "/Users/awhite48/Projects/phrom/crates/panproto-expr-parser" } 31+panproto-xrpc = { path = "/Users/awhite48/Projects/phrom/crates/panproto-xrpc" } 32+panproto-parse = { path = "/Users/awhite48/Projects/phrom/crates/panproto-parse", features = ["group-all"] } 33+panproto-git = { path = "/Users/awhite48/Projects/phrom/crates/panproto-git" } 34+panproto-project = { path = "/Users/awhite48/Projects/phrom/crates/panproto-project" } 3535 git2 = "0.20" 3636 3737 # Web framework
@@ -19,7 +19,7 @@ panproto-mig.workspace = true
1919 panproto-inst.workspace = true 2020 panproto-lens.workspace = true 2121 panproto-expr.workspace = true 22-panproto-expr-parser.workspace = true 22+panproto-lens-dsl.workspace = true 2323 panproto-check.workspace = true 2424 panproto-gat.workspace = true 2525
@@ -20,10 +20,8 @@ pub fn emit_all_views_from_lenses(
2020 2121 for lens in crate::lens_config::db_projection_lenses(lenses) { 2222 if let Some((schema, _)) = schemas.iter().find(|(_, nsid)| nsid == &lens.source) { 23- let body_id = find_record_body(schema, &lens.source); 24- let chain = crate::lens_config::steps_to_protolens_chain(&lens.steps, &body_id); 2523 let protocol = Protocol::default(); 26- let target = match chain.instantiate(schema, &protocol) { 24+ let target = match lens.chain.instantiate(schema, &protocol) { 2725 Ok(l) => l.tgt_schema, 2826 Err(e) => { 2927 eprintln!(" warn: lens instantiation for {}: {e:?}", lens.source);
@@ -31,8 +29,8 @@ pub fn emit_all_views_from_lenses(
3129 } 3230 }; 3331 34- let table = lens.table.as_ref(); 35- let view_name = table 32+ let table = crate::lens_config::table_config(lens); 33+ let view_name = table.as_ref() 3634 .map(|t| { 3735 t.row_struct 3836 .strip_suffix("Row")
@@ -41,10 +39,10 @@ pub fn emit_all_views_from_lenses(
4139 + "View" 4240 }) 4341 .unwrap_or_else(|| nsid_to_pascal(&lens.source) + "View"); 44- let include_did = table.map(|t| t.include_did).unwrap_or(true); 45- let include_rkey = table.map(|t| t.include_rkey).unwrap_or(true); 42+ let include_did = table.as_ref().map(|t| t.include_did).unwrap_or(true); 43+ let include_rkey = table.as_ref().map(|t| t.include_rkey).unwrap_or(true); 4644 let empty_defaults = std::collections::HashMap::new(); 47- let column_defaults = table 45+ let column_defaults = table.as_ref() 4846 .map(|t| &t.column_defaults) 4947 .unwrap_or(&empty_defaults); 5048
@@ -1,83 +1,66 @@
1-//! Load human-readable lens JSON files and convert to panproto ProtolensChain. 1+//! Load lens files via panproto-lens-dsl. 22 //! 3-//! Lens files use a concise DSL: 4-//! { "remove_field": "fieldName" } → combinators::remove_field 5-//! { "rename_field": { "old": "x", "new": "y" } } → combinators::rename_field 6-//! { "add_field": { "name": "x", "kind": "string", "default": "" } } → combinators::add_field 7-//! { "add_field": { ..., "expr": "head(split(...))" } } → add_field + ComputeField 8-//! { "apply_expr": { "field": "x", "expr": "match(...)" } } → ApplyExpr 9-//! { "compute_field": { "target": "x", "expr": "concat(...)" } } → ComputeField 10-//! 11-//! Schema-level steps (remove, rename, add) → ProtolensChain via panproto combinators. 12-//! Value-level steps (expr, compute) → FieldTransforms via panproto expression parser. 13-//! Both come from the same JSON file; they're applied at different levels. 3+//! Thin wrapper around panproto_lens_dsl for cospan-specific conventions 4+//! (db-projection vs interop lens IDs, table metadata in extensions). 145 156 use std::collections::HashMap; 167 use std::path::Path; 178 189 use anyhow::{Context, Result}; 19-use panproto_gat::{CoercionClass, Name}; 20-use panproto_inst::value::Value; 21-use panproto_inst::FieldTransform; 22-use panproto_lens::{combinators, ProtolensChain}; 23-use serde::Deserialize; 10+use panproto_lens_dsl::CompiledLens; 2411 25-/// A human-readable lens file. 26-#[derive(Debug, Deserialize)] 27-pub struct LensFile { 28- #[serde(rename = "$type")] 29- pub type_id: String, 30- pub id: String, 31- #[serde(default)] 32- pub description: String, 33- pub source: String, 34- pub target: String, 35- pub steps: Vec<LensStep>, 36- #[serde(default)] 37- pub table: Option<TableConfig>, 38-} 12+/// Type alias for backward compatibility. 13+pub type LensFile = CompiledLens; 14+ 15+/// Load and compile all lens files from a directory. 16+pub fn load_all_lenses(lenses_dir: &Path) -> Result<Vec<CompiledLens>> { 17+ if !lenses_dir.exists() { 18+ return Ok(Vec::new()); 19+ } 20+ 21+ let result = panproto_lens_dsl::load_dir(lenses_dir) 22+ .with_context(|| format!("loading lenses from {}", lenses_dir.display()))?; 23+ 24+ for (path, err) in &result.errors { 25+ eprintln!(" warn: failed to load {}: {err}", path.display()); 26+ } 27+ 28+ let resolver = |_id: &str| -> Option<CompiledLens> { None }; 29+ let mut compiled = Vec::new(); 30+ 31+ for doc in &result.documents { 32+ let body_vertex = format!("{}:body", doc.source); 33+ match panproto_lens_dsl::compile(doc, &body_vertex, &resolver) { 34+ Ok(c) => compiled.push(c), 35+ Err(e) => eprintln!(" warn: compile lens {}: {e}", doc.id), 36+ } 37+ } 3938 40-/// A single step in the lens pipeline. 41-#[derive(Debug, Deserialize)] 42-#[serde(untagged)] 43-pub enum LensStep { 44- RemoveField { remove_field: String }, 45- RenameField { rename_field: RenameSpec }, 46- AddField { add_field: AddFieldSpec }, 47- ApplyExpr { apply_expr: ApplyExprSpec }, 48- ComputeField { compute_field: ComputeFieldSpec }, 39+ Ok(compiled) 4940 } 5041 51-#[derive(Debug, Deserialize)] 52-pub struct RenameSpec { 53- pub old: String, 54- pub new: String, 42+/// DB projection lenses (id ending in ".db-projection"). 43+pub fn db_projection_lenses(lenses: &[CompiledLens]) -> Vec<&CompiledLens> { 44+ lenses.iter().filter(|l| l.id.ends_with(".db-projection")).collect() 5545 } 5646 57-#[derive(Debug, Deserialize)] 58-pub struct AddFieldSpec { 59- pub name: String, 60- pub kind: String, 61- #[serde(default)] 62- pub default: serde_json::Value, 63- #[serde(default)] 64- pub expr: Option<String>, 47+/// Interop lenses (id ending in ".interop"). 48+pub fn interop_lenses(lenses: &[CompiledLens]) -> Vec<&CompiledLens> { 49+ lenses.iter().filter(|l| l.id.ends_with(".interop")).collect() 6550 } 6651 67-#[derive(Debug, Deserialize)] 68-pub struct ApplyExprSpec { 69- pub field: String, 70- pub expr: String, 52+/// Find a compiled lens by source NSID. 53+pub fn find_by_source<'a>(lenses: &'a [CompiledLens], source: &str) -> Option<&'a CompiledLens> { 54+ lenses.iter().find(|l| l.source == source) 7155 } 7256 73-#[derive(Debug, Deserialize)] 74-pub struct ComputeFieldSpec { 75- pub target: String, 76- pub expr: String, 57+/// Extract table config from the lens's extensions. 58+pub fn table_config(lens: &CompiledLens) -> Option<TableConfig> { 59+ lens.extensions.get("table").and_then(|v| serde_json::from_value(v.clone()).ok()) 7760 } 7861 79-/// DDL metadata (optional, only for db-projection lenses). 80-#[derive(Debug, Deserialize)] 62+/// DDL metadata from the "table" extension. 63+#[derive(Debug, serde::Deserialize)] 8164 pub struct TableConfig { 8265 pub name: String, 8366 pub row_struct: String,
@@ -89,180 +72,9 @@ pub struct TableConfig {
8972 #[serde(default = "default_true")] 9073 pub include_rkey: bool, 9174 #[serde(default)] 92- pub indexes: Vec<serde_json::Value>, 93- #[serde(default)] 94- pub foreign_keys: Vec<serde_json::Value>, 95- #[serde(default)] 9675 pub column_defaults: HashMap<String, String>, 9776 #[serde(default)] 9877 pub counter_fields: Vec<String>, 9978 } 10079 10180 fn default_true() -> bool { true } 102- 103-/// Load all lens files from a directory. 104-pub fn load_all_lenses(lenses_dir: &Path) -> Result<Vec<LensFile>> { 105- let mut lenses = Vec::new(); 106- if !lenses_dir.exists() { 107- return Ok(lenses); 108- } 109- for entry in std::fs::read_dir(lenses_dir)? { 110- let path = entry?.path(); 111- if path.extension().and_then(|e| e.to_str()) == Some("json") { 112- let json_str = std::fs::read_to_string(&path) 113- .with_context(|| format!("reading {}", path.display()))?; 114- let lens: LensFile = serde_json::from_str(&json_str) 115- .with_context(|| format!("parsing {}", path.display()))?; 116- lenses.push(lens); 117- } 118- } 119- Ok(lenses) 120-} 121- 122-/// Convert schema-level steps to a ProtolensChain using panproto combinators. 123-pub fn steps_to_protolens_chain(steps: &[LensStep], body_id: &str) -> ProtolensChain { 124- let mut chains: Vec<ProtolensChain> = Vec::new(); 125- 126- for step in steps { 127- match step { 128- LensStep::RemoveField { remove_field } => { 129- let vertex_id = format!("{body_id}.{remove_field}"); 130- chains.push(combinators::remove_field(vertex_id)); 131- } 132- LensStep::RenameField { rename_field } => { 133- let field_vertex = format!("{body_id}.{}", rename_field.old); 134- chains.push(combinators::rename_field( 135- body_id, 136- &*field_vertex, 137- &*rename_field.old, 138- &*rename_field.new, 139- )); 140- } 141- LensStep::AddField { add_field } => { 142- let vertex_id = format!("{body_id}.{}", add_field.name); 143- let default = json_to_value(&add_field.default, &add_field.kind); 144- chains.push(combinators::add_field( 145- body_id, 146- &*vertex_id, 147- &*add_field.kind, 148- default, 149- )); 150- } 151- // Expression steps are value-level, not schema-level — handled by 152- // steps_to_value_transforms, not by protolens combinators. 153- LensStep::ApplyExpr { .. } | LensStep::ComputeField { .. } => {} 154- } 155- } 156- 157- combinators::pipeline(chains) 158-} 159- 160-/// Extract value-level transforms (expressions) from lens steps. 161-/// 162-/// These are injected into the CompiledMigration's field_transforms after 163-/// the schema-level chain is instantiated. Uses panproto_expr_parser to 164-/// parse expression strings from the lens JSON. 165-pub fn steps_to_value_transforms( 166- steps: &[LensStep], 167- body_vertex: &str, 168-) -> HashMap<Name, Vec<FieldTransform>> { 169- let mut transforms: HashMap<Name, Vec<FieldTransform>> = HashMap::new(); 170- let key = Name::from(body_vertex); 171- 172- for step in steps { 173- match step { 174- LensStep::AddField { add_field } if add_field.expr.is_some() => { 175- let expr_str = add_field.expr.as_ref().unwrap(); 176- if let Some(expr) = parse_expr(expr_str) { 177- transforms.entry(key.clone()).or_default().push( 178- FieldTransform::ComputeField { 179- target_key: add_field.name.clone(), 180- expr, 181- inverse: None, 182- coercion_class: CoercionClass::Projection, 183- }, 184- ); 185- } 186- } 187- LensStep::ApplyExpr { apply_expr } => { 188- if let Some(expr) = parse_expr(&apply_expr.expr) { 189- transforms.entry(key.clone()).or_default().push( 190- FieldTransform::ApplyExpr { 191- key: apply_expr.field.clone(), 192- expr, 193- inverse: None, 194- coercion_class: CoercionClass::Projection, 195- }, 196- ); 197- } 198- } 199- LensStep::ComputeField { compute_field } => { 200- if let Some(expr) = parse_expr(&compute_field.expr) { 201- transforms.entry(key.clone()).or_default().push( 202- FieldTransform::ComputeField { 203- target_key: compute_field.target.clone(), 204- expr, 205- inverse: None, 206- coercion_class: CoercionClass::Projection, 207- }, 208- ); 209- } 210- } 211- _ => {} 212- } 213- } 214- 215- transforms 216-} 217- 218-/// Parse a panproto expression string using panproto_expr_parser. 219-fn parse_expr(expr_str: &str) -> Option<panproto_expr::Expr> { 220- let tokens = match panproto_expr_parser::tokenize(expr_str) { 221- Ok(t) => t, 222- Err(e) => { 223- eprintln!(" warn: failed to tokenize expression '{expr_str}': {e}"); 224- return None; 225- } 226- }; 227- match panproto_expr_parser::parse(&tokens) { 228- Ok(expr) => Some(expr), 229- Err(errors) => { 230- for e in &errors { 231- eprintln!(" warn: parse error in expression '{expr_str}': {e}"); 232- } 233- None 234- } 235- } 236-} 237- 238-/// Convert a JSON default value to a panproto Value. 239-fn json_to_value(json: &serde_json::Value, kind: &str) -> Value { 240- match json { 241- serde_json::Value::Null => Value::Null, 242- serde_json::Value::String(s) => Value::Str(s.clone()), 243- serde_json::Value::Number(n) => { 244- if let Some(i) = n.as_i64() { Value::Int(i) } 245- else if let Some(f) = n.as_f64() { Value::Float(f) } 246- else { Value::Int(0) } 247- } 248- serde_json::Value::Bool(b) => Value::Bool(*b), 249- _ => match kind { 250- "integer" => Value::Int(0), 251- "number" | "float" => Value::Float(0.0), 252- "boolean" => Value::Bool(false), 253- _ => Value::Str(String::new()), 254- }, 255- } 256-} 257- 258-pub fn db_projection_lenses(lenses: &[LensFile]) -> Vec<&LensFile> { 259- lenses.iter().filter(|l| l.id.ends_with(".db-projection")).collect() 260-} 261- 262-pub fn interop_lenses(lenses: &[LensFile]) -> Vec<&LensFile> { 263- lenses.iter().filter(|l| l.id.ends_with(".interop")).collect() 264-} 265- 266-pub fn find_by_source<'a>(lenses: &'a [LensFile], source_nsid: &str) -> Option<&'a LensFile> { 267- lenses.iter().find(|l| l.source == source_nsid) 268-}