Compare commits
1 Commits
6bf40684b9
...
56b6c187c7
Author | SHA1 | Date |
---|---|---|
Savanni D'Gerinel | 56b6c187c7 |
|
@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "1.0.5"
|
version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783"
|
checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
@ -70,9 +70,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
version = "0.21.3"
|
version = "0.21.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53"
|
checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bit-set"
|
name = "bit-set"
|
||||||
|
@ -139,7 +139,7 @@ checksum = "ab3603c4028a5e368d09b51c8b624b9a46edcd7c3778284077a6125af73c9f0a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"cairo-sys-rs",
|
"cairo-sys-rs",
|
||||||
"glib 0.17.10",
|
"glib",
|
||||||
"libc",
|
"libc",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
@ -151,7 +151,7 @@ version = "0.17.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "691d0c66b1fb4881be80a760cb8fe76ea97218312f9dfe2c9cc0f496ca279cb1"
|
checksum = "691d0c66b1fb4881be80a760cb8fe76ea97218312f9dfe2c9cc0f496ca279cb1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glib-sys 0.17.10",
|
"glib-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"system-deps",
|
"system-deps",
|
||||||
]
|
]
|
||||||
|
@ -190,9 +190,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chrono"
|
name = "chrono"
|
||||||
version = "0.4.27"
|
version = "0.4.26"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f56b4c72906975ca04becb8a30e102dfecddd0c06181e3e95ddc444be28881f8"
|
checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"android-tzdata",
|
"android-tzdata",
|
||||||
"iana-time-zone",
|
"iana-time-zone",
|
||||||
|
@ -201,7 +201,7 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"time",
|
"time",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"windows-targets",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -349,8 +349,8 @@ name = "cyberpunk-splash"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cairo-rs",
|
"cairo-rs",
|
||||||
"gio 0.17.10",
|
"gio",
|
||||||
"glib 0.17.10",
|
"glib",
|
||||||
"gtk4",
|
"gtk4",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -365,8 +365,8 @@ dependencies = [
|
||||||
"futures",
|
"futures",
|
||||||
"gdk4",
|
"gdk4",
|
||||||
"geo-types",
|
"geo-types",
|
||||||
"gio 0.17.10",
|
"gio",
|
||||||
"glib 0.17.10",
|
"glib",
|
||||||
"glib-build-tools 0.16.3",
|
"glib-build-tools 0.16.3",
|
||||||
"gtk4",
|
"gtk4",
|
||||||
"ifc",
|
"ifc",
|
||||||
|
@ -442,9 +442,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "errno"
|
name = "errno"
|
||||||
version = "0.3.3"
|
version = "0.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd"
|
checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"errno-dragonfly",
|
"errno-dragonfly",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -713,8 +713,8 @@ checksum = "695d6bc846438c5708b07007537b9274d883373dd30858ca881d7d71b5540717"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"gdk-pixbuf-sys",
|
"gdk-pixbuf-sys",
|
||||||
"gio 0.17.10",
|
"gio",
|
||||||
"glib 0.17.10",
|
"glib",
|
||||||
"libc",
|
"libc",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
]
|
]
|
||||||
|
@ -725,9 +725,9 @@ version = "0.17.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9285ec3c113c66d7d0ab5676599176f1f42f4944ca1b581852215bf5694870cb"
|
checksum = "9285ec3c113c66d7d0ab5676599176f1f42f4944ca1b581852215bf5694870cb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gio-sys 0.17.10",
|
"gio-sys",
|
||||||
"glib-sys 0.17.10",
|
"glib-sys",
|
||||||
"gobject-sys 0.17.10",
|
"gobject-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"system-deps",
|
"system-deps",
|
||||||
]
|
]
|
||||||
|
@ -742,10 +742,10 @@ dependencies = [
|
||||||
"cairo-rs",
|
"cairo-rs",
|
||||||
"gdk-pixbuf",
|
"gdk-pixbuf",
|
||||||
"gdk4-sys",
|
"gdk4-sys",
|
||||||
"gio 0.17.10",
|
"gio",
|
||||||
"glib 0.17.10",
|
"glib",
|
||||||
"libc",
|
"libc",
|
||||||
"pango 0.17.10",
|
"pango",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -756,11 +756,11 @@ checksum = "1bc92aa1608c089c49393d014c38ac0390d01e4841e1fedaa75dbcef77aaed64"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cairo-sys-rs",
|
"cairo-sys-rs",
|
||||||
"gdk-pixbuf-sys",
|
"gdk-pixbuf-sys",
|
||||||
"gio-sys 0.17.10",
|
"gio-sys",
|
||||||
"glib-sys 0.17.10",
|
"glib-sys",
|
||||||
"gobject-sys 0.17.10",
|
"gobject-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"pango-sys 0.17.10",
|
"pango-sys",
|
||||||
"pkg-config",
|
"pkg-config",
|
||||||
"system-deps",
|
"system-deps",
|
||||||
]
|
]
|
||||||
|
@ -818,27 +818,8 @@ dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-io",
|
"futures-io",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"gio-sys 0.17.10",
|
"gio-sys",
|
||||||
"glib 0.17.10",
|
"glib",
|
||||||
"libc",
|
|
||||||
"once_cell",
|
|
||||||
"pin-project-lite",
|
|
||||||
"smallvec",
|
|
||||||
"thiserror",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gio"
|
|
||||||
version = "0.18.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7884cba6b1c5db1607d970cadf44b14a43913d42bc68766eea6a5e2fe0891524"
|
|
||||||
dependencies = [
|
|
||||||
"futures-channel",
|
|
||||||
"futures-core",
|
|
||||||
"futures-io",
|
|
||||||
"futures-util",
|
|
||||||
"gio-sys 0.18.1",
|
|
||||||
"glib 0.18.1",
|
|
||||||
"libc",
|
"libc",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
@ -852,21 +833,8 @@ version = "0.17.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0ccf87c30a12c469b6d958950f6a9c09f2be20b7773f7e70d20b867fdf2628c3"
|
checksum = "0ccf87c30a12c469b6d958950f6a9c09f2be20b7773f7e70d20b867fdf2628c3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glib-sys 0.17.10",
|
"glib-sys",
|
||||||
"gobject-sys 0.17.10",
|
"gobject-sys",
|
||||||
"libc",
|
|
||||||
"system-deps",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gio-sys"
|
|
||||||
version = "0.18.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "37566df850baf5e4cb0dfb78af2e4b9898d817ed9263d1090a2df958c64737d2"
|
|
||||||
dependencies = [
|
|
||||||
"glib-sys 0.18.1",
|
|
||||||
"gobject-sys 0.18.0",
|
|
||||||
"libc",
|
"libc",
|
||||||
"system-deps",
|
"system-deps",
|
||||||
"winapi",
|
"winapi",
|
||||||
|
@ -884,33 +852,10 @@ dependencies = [
|
||||||
"futures-executor",
|
"futures-executor",
|
||||||
"futures-task",
|
"futures-task",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"gio-sys 0.17.10",
|
"gio-sys",
|
||||||
"glib-macros 0.17.10",
|
"glib-macros",
|
||||||
"glib-sys 0.17.10",
|
"glib-sys",
|
||||||
"gobject-sys 0.17.10",
|
"gobject-sys",
|
||||||
"libc",
|
|
||||||
"memchr",
|
|
||||||
"once_cell",
|
|
||||||
"smallvec",
|
|
||||||
"thiserror",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "glib"
|
|
||||||
version = "0.18.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "331156127e8166dd815cf8d2db3a5beb492610c716c03ee6db4f2d07092af0a7"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags 2.4.0",
|
|
||||||
"futures-channel",
|
|
||||||
"futures-core",
|
|
||||||
"futures-executor",
|
|
||||||
"futures-task",
|
|
||||||
"futures-util",
|
|
||||||
"gio-sys 0.18.1",
|
|
||||||
"glib-macros 0.18.0",
|
|
||||||
"glib-sys 0.18.1",
|
|
||||||
"gobject-sys 0.18.0",
|
|
||||||
"libc",
|
"libc",
|
||||||
"memchr",
|
"memchr",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
@ -945,20 +890,6 @@ dependencies = [
|
||||||
"syn 1.0.109",
|
"syn 1.0.109",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "glib-macros"
|
|
||||||
version = "0.18.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "179643c50bf28d20d2f6eacd2531a88f2f5d9747dd0b86b8af1e8bb5dd0de3c0"
|
|
||||||
dependencies = [
|
|
||||||
"heck",
|
|
||||||
"proc-macro-crate",
|
|
||||||
"proc-macro-error",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.29",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glib-sys"
|
name = "glib-sys"
|
||||||
version = "0.17.10"
|
version = "0.17.10"
|
||||||
|
@ -969,16 +900,6 @@ dependencies = [
|
||||||
"system-deps",
|
"system-deps",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "glib-sys"
|
|
||||||
version = "0.18.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "063ce2eb6a8d0ea93d2bf8ba1957e78dbab6be1c2220dd3daca57d5a9d869898"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"system-deps",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gm-control-panel"
|
name = "gm-control-panel"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -987,8 +908,8 @@ dependencies = [
|
||||||
"config-derive",
|
"config-derive",
|
||||||
"futures",
|
"futures",
|
||||||
"gdk4",
|
"gdk4",
|
||||||
"gio 0.17.10",
|
"gio",
|
||||||
"glib 0.17.10",
|
"glib",
|
||||||
"glib-build-tools 0.16.3",
|
"glib-build-tools 0.16.3",
|
||||||
"gtk4",
|
"gtk4",
|
||||||
"libadwaita",
|
"libadwaita",
|
||||||
|
@ -1003,18 +924,7 @@ version = "0.17.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cd34c3317740a6358ec04572c1bcfd3ac0b5b6529275fae255b237b314bb8062"
|
checksum = "cd34c3317740a6358ec04572c1bcfd3ac0b5b6529275fae255b237b314bb8062"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glib-sys 0.17.10",
|
"glib-sys",
|
||||||
"libc",
|
|
||||||
"system-deps",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gobject-sys"
|
|
||||||
version = "0.18.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0850127b514d1c4a4654ead6dedadb18198999985908e6ffe4436f53c785ce44"
|
|
||||||
dependencies = [
|
|
||||||
"glib-sys 0.18.1",
|
|
||||||
"libc",
|
"libc",
|
||||||
"system-deps",
|
"system-deps",
|
||||||
]
|
]
|
||||||
|
@ -1025,7 +935,7 @@ version = "0.17.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "def4bb01265b59ed548b05455040d272d989b3012c42d4c1bbd39083cb9b40d9"
|
checksum = "def4bb01265b59ed548b05455040d272d989b3012c42d4c1bbd39083cb9b40d9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glib 0.17.10",
|
"glib",
|
||||||
"graphene-sys",
|
"graphene-sys",
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
@ -1036,7 +946,7 @@ version = "0.17.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1856fc817e6a6675e36cea0bd9a3afe296f5d9709d1e2d3182803ac77f0ab21d"
|
checksum = "1856fc817e6a6675e36cea0bd9a3afe296f5d9709d1e2d3182803ac77f0ab21d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glib-sys 0.17.10",
|
"glib-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"pkg-config",
|
"pkg-config",
|
||||||
"system-deps",
|
"system-deps",
|
||||||
|
@ -1060,11 +970,11 @@ dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"cairo-rs",
|
"cairo-rs",
|
||||||
"gdk4",
|
"gdk4",
|
||||||
"glib 0.17.10",
|
"glib",
|
||||||
"graphene-rs",
|
"graphene-rs",
|
||||||
"gsk4-sys",
|
"gsk4-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"pango 0.17.10",
|
"pango",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1075,11 +985,11 @@ checksum = "c07a84fb4dcf1323d29435aa85e2f5f58bef564342bef06775ec7bd0da1f01b0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cairo-sys-rs",
|
"cairo-sys-rs",
|
||||||
"gdk4-sys",
|
"gdk4-sys",
|
||||||
"glib-sys 0.17.10",
|
"glib-sys",
|
||||||
"gobject-sys 0.17.10",
|
"gobject-sys",
|
||||||
"graphene-sys",
|
"graphene-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"pango-sys 0.17.10",
|
"pango-sys",
|
||||||
"system-deps",
|
"system-deps",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1095,15 +1005,15 @@ dependencies = [
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"gdk-pixbuf",
|
"gdk-pixbuf",
|
||||||
"gdk4",
|
"gdk4",
|
||||||
"gio 0.17.10",
|
"gio",
|
||||||
"glib 0.17.10",
|
"glib",
|
||||||
"graphene-rs",
|
"graphene-rs",
|
||||||
"gsk4",
|
"gsk4",
|
||||||
"gtk4-macros",
|
"gtk4-macros",
|
||||||
"gtk4-sys",
|
"gtk4-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"pango 0.17.10",
|
"pango",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1129,13 +1039,13 @@ dependencies = [
|
||||||
"cairo-sys-rs",
|
"cairo-sys-rs",
|
||||||
"gdk-pixbuf-sys",
|
"gdk-pixbuf-sys",
|
||||||
"gdk4-sys",
|
"gdk4-sys",
|
||||||
"gio-sys 0.17.10",
|
"gio-sys",
|
||||||
"glib-sys 0.17.10",
|
"glib-sys",
|
||||||
"gobject-sys 0.17.10",
|
"gobject-sys",
|
||||||
"graphene-sys",
|
"graphene-sys",
|
||||||
"gsk4-sys",
|
"gsk4-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"pango-sys 0.17.10",
|
"pango-sys",
|
||||||
"system-deps",
|
"system-deps",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1197,8 +1107,8 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cairo-rs",
|
"cairo-rs",
|
||||||
"coordinates",
|
"coordinates",
|
||||||
"gio 0.17.10",
|
"gio",
|
||||||
"glib 0.17.10",
|
"glib",
|
||||||
"glib-build-tools 0.16.3",
|
"glib-build-tools 0.16.3",
|
||||||
"gtk4",
|
"gtk4",
|
||||||
"image",
|
"image",
|
||||||
|
@ -1425,7 +1335,6 @@ dependencies = [
|
||||||
"sgf",
|
"sgf",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"typeshare",
|
"typeshare",
|
||||||
"uuid 1.4.1",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1433,14 +1342,14 @@ name = "kifu-gtk"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cairo-rs",
|
"cairo-rs",
|
||||||
"gio 0.17.10",
|
"gio",
|
||||||
"glib 0.17.10",
|
"glib",
|
||||||
"glib-build-tools 0.17.10",
|
"glib-build-tools 0.17.10",
|
||||||
"gtk4",
|
"gtk4",
|
||||||
"image",
|
"image",
|
||||||
"kifu-core",
|
"kifu-core",
|
||||||
"libadwaita",
|
"libadwaita",
|
||||||
"pango 0.18.0",
|
"pango",
|
||||||
"sgf",
|
"sgf",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
@ -1466,12 +1375,12 @@ dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"gdk-pixbuf",
|
"gdk-pixbuf",
|
||||||
"gdk4",
|
"gdk4",
|
||||||
"gio 0.17.10",
|
"gio",
|
||||||
"glib 0.17.10",
|
"glib",
|
||||||
"gtk4",
|
"gtk4",
|
||||||
"libadwaita-sys",
|
"libadwaita-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"pango 0.17.10",
|
"pango",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1481,12 +1390,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4231cb2499a9f0c4cdfa4885414b33e39901ddcac61150bc0bb4ff8a57ede404"
|
checksum = "4231cb2499a9f0c4cdfa4885414b33e39901ddcac61150bc0bb4ff8a57ede404"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gdk4-sys",
|
"gdk4-sys",
|
||||||
"gio-sys 0.17.10",
|
"gio-sys",
|
||||||
"glib-sys 0.17.10",
|
"glib-sys",
|
||||||
"gobject-sys 0.17.10",
|
"gobject-sys",
|
||||||
"gtk4-sys",
|
"gtk4-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"pango-sys 0.17.10",
|
"pango-sys",
|
||||||
"system-deps",
|
"system-deps",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1526,9 +1435,9 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.6.1"
|
version = "2.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f478948fd84d9f8e86967bf432640e46adfb5a4bd4f14ef7e864ab38220534ae"
|
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memoffset"
|
name = "memoffset"
|
||||||
|
@ -1684,11 +1593,11 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl"
|
name = "openssl"
|
||||||
version = "0.10.57"
|
version = "0.10.56"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c"
|
checksum = "729b745ad4a5575dd06a3e1af1414bd330ee561c01b3899eb584baeaa8def17e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.4.0",
|
"bitflags 1.3.2",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"foreign-types",
|
"foreign-types",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -1716,9 +1625,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl-sys"
|
name = "openssl-sys"
|
||||||
version = "0.9.92"
|
version = "0.9.91"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "db7e971c2c2bba161b2d2fdf37080177eff520b3bc044787c7f1f5f9e78d869b"
|
checksum = "866b5f16f90776b9bb8dc1e1802ac6f0513de3a7a7465867bfbc563dc737faac"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -1733,24 +1642,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "35be456fc620e61f62dff7ff70fbd54dcbaf0a4b920c0f16de1107c47d921d48"
|
checksum = "35be456fc620e61f62dff7ff70fbd54dcbaf0a4b920c0f16de1107c47d921d48"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"gio 0.17.10",
|
"gio",
|
||||||
"glib 0.17.10",
|
"glib",
|
||||||
"libc",
|
"libc",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"pango-sys 0.17.10",
|
"pango-sys",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pango"
|
|
||||||
version = "0.18.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "06a9e54b831d033206160096b825f2070cf5fda7e35167b1c01e9e774f9202d1"
|
|
||||||
dependencies = [
|
|
||||||
"gio 0.18.1",
|
|
||||||
"glib 0.18.1",
|
|
||||||
"libc",
|
|
||||||
"once_cell",
|
|
||||||
"pango-sys 0.18.0",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1759,20 +1655,8 @@ version = "0.17.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3da69f9f3850b0d8990d462f8c709561975e95f689c1cdf0fecdebde78b35195"
|
checksum = "3da69f9f3850b0d8990d462f8c709561975e95f689c1cdf0fecdebde78b35195"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glib-sys 0.17.10",
|
"glib-sys",
|
||||||
"gobject-sys 0.17.10",
|
"gobject-sys",
|
||||||
"libc",
|
|
||||||
"system-deps",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pango-sys"
|
|
||||||
version = "0.18.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "436737e391a843e5933d6d9aa102cb126d501e815b83601365a948a518555dc5"
|
|
||||||
dependencies = [
|
|
||||||
"glib-sys 0.18.1",
|
|
||||||
"gobject-sys 0.18.0",
|
|
||||||
"libc",
|
"libc",
|
||||||
"system-deps",
|
"system-deps",
|
||||||
]
|
]
|
||||||
|
@ -1875,9 +1759,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-lite"
|
name = "pin-project-lite"
|
||||||
version = "0.2.13"
|
version = "0.2.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
|
checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-utils"
|
name = "pin-utils"
|
||||||
|
@ -2069,25 +1953,25 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.9.4"
|
version = "1.9.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "12de2eff854e5fa4b1295edd650e227e9d8fb0c9e90b12e7f36d6a6811791a29"
|
checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
"regex-automata",
|
"regex-automata",
|
||||||
"regex-syntax 0.7.5",
|
"regex-syntax 0.7.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-automata"
|
name = "regex-automata"
|
||||||
version = "0.3.7"
|
version = "0.3.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "49530408a136e16e5b486e883fbb6ba058e8e4e8ae6621a77b048b314336e629"
|
checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
"regex-syntax 0.7.5",
|
"regex-syntax 0.7.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2098,9 +1982,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.7.5"
|
version = "0.7.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
|
checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "reqwest"
|
name = "reqwest"
|
||||||
|
@ -2162,9 +2046,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
version = "0.38.10"
|
version = "0.38.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ed6248e1caa625eb708e266e06159f135e8c26f2bb7ceb72dc4b2766d0340964"
|
checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.4.0",
|
"bitflags 2.4.0",
|
||||||
"errno",
|
"errno",
|
||||||
|
@ -2250,18 +2134,18 @@ checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.188"
|
version = "1.0.186"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e"
|
checksum = "9f5db24220c009de9bd45e69fb2938f4b6d2df856aa9304ce377b3180f83b7c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.188"
|
version = "1.0.186"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
|
checksum = "5ad697f7e0b65af4983a4ce8f56ed5b357e8d3c36651bf6a7e13639c17b8e670"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -2305,7 +2189,6 @@ name = "sgf"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"cool_asserts",
|
|
||||||
"nom",
|
"nom",
|
||||||
"serde",
|
"serde",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
@ -2701,9 +2584,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "url"
|
name = "url"
|
||||||
version = "2.4.1"
|
version = "2.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5"
|
checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"form_urlencoded",
|
"form_urlencoded",
|
||||||
"idna",
|
"idna",
|
||||||
|
|
|
@ -15,7 +15,6 @@ serde_json = { version = "1" }
|
||||||
serde = { version = "1", features = [ "derive" ] }
|
serde = { version = "1", features = [ "derive" ] }
|
||||||
thiserror = { version = "1" }
|
thiserror = { version = "1" }
|
||||||
typeshare = { version = "1" }
|
typeshare = { version = "1" }
|
||||||
uuid = { version = "1.4", features = [ "v4" ] }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
cool_asserts = { version = "2" }
|
cool_asserts = { version = "2" }
|
||||||
|
|
|
@ -11,7 +11,6 @@ use std::{
|
||||||
sync::{Arc, RwLock},
|
sync::{Arc, RwLock},
|
||||||
};
|
};
|
||||||
use typeshare::typeshare;
|
use typeshare::typeshare;
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
#[typeshare]
|
#[typeshare]
|
||||||
|
@ -21,7 +20,7 @@ pub enum CoreRequest {
|
||||||
CreateGame(CreateGameRequest),
|
CreateGame(CreateGameRequest),
|
||||||
Home,
|
Home,
|
||||||
OpenConfiguration,
|
OpenConfiguration,
|
||||||
OpenGameReview(GameId),
|
OpenGameReview,
|
||||||
PlayingField,
|
PlayingField,
|
||||||
PlayStone(PlayStoneRequest),
|
PlayStone(PlayStoneRequest),
|
||||||
StartGame,
|
StartGame,
|
||||||
|
@ -38,16 +37,10 @@ pub enum CoreResponse {
|
||||||
UpdatedConfigurationView(ConfigurationView),
|
UpdatedConfigurationView(ConfigurationView),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
#[typeshare]
|
#[typeshare]
|
||||||
pub struct GameId(String);
|
pub struct GameId(String);
|
||||||
|
|
||||||
impl GameId {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
GameId(Uuid::new_v4().hyphenated().to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
#[typeshare]
|
#[typeshare]
|
||||||
#[serde(tag = "type", content = "content")]
|
#[serde(tag = "type", content = "content")]
|
||||||
|
@ -147,11 +140,7 @@ impl CoreApp {
|
||||||
CoreRequest::OpenConfiguration => {
|
CoreRequest::OpenConfiguration => {
|
||||||
CoreResponse::ConfigurationView(configuration(&self.config.read().unwrap()))
|
CoreResponse::ConfigurationView(configuration(&self.config.read().unwrap()))
|
||||||
}
|
}
|
||||||
CoreRequest::OpenGameReview(game_id) => {
|
CoreRequest::OpenGameReview => CoreResponse::GameReview(review()),
|
||||||
let state = self.state.read().unwrap();
|
|
||||||
let game = state.database.get(&game_id).unwrap();
|
|
||||||
CoreResponse::GameReview(review(game))
|
|
||||||
}
|
|
||||||
CoreRequest::PlayingField => {
|
CoreRequest::PlayingField => {
|
||||||
let app_state = self.state.read().unwrap();
|
let app_state = self.state.read().unwrap();
|
||||||
let game = app_state.game.as_ref().unwrap();
|
let game = app_state.game.as_ref().unwrap();
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
use sgf::{go, parse_sgf, Game};
|
use std::{ffi::OsStr, io::Read, os::unix::ffi::OsStrExt, path::PathBuf};
|
||||||
use std::{collections::HashMap, ffi::OsStr, io::Read, os::unix::ffi::OsStrExt, path::PathBuf};
|
|
||||||
use thiserror::Error;
|
|
||||||
|
|
||||||
use crate::api::GameId;
|
use sgf::{go, parse_sgf, Game};
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
@ -21,12 +20,12 @@ impl From<std::io::Error> for Error {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Database {
|
pub struct Database {
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
games: HashMap<GameId, go::Game>,
|
games: Vec<go::Game>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Database {
|
impl Database {
|
||||||
pub fn open_path(path: PathBuf) -> Result<Database, Error> {
|
pub fn open_path(path: PathBuf) -> Result<Database, Error> {
|
||||||
let mut games: HashMap<GameId, go::Game> = HashMap::new();
|
let mut games: Vec<go::Game> = Vec::new();
|
||||||
|
|
||||||
let extension = PathBuf::from("sgf").into_os_string();
|
let extension = PathBuf::from("sgf").into_os_string();
|
||||||
|
|
||||||
|
@ -44,9 +43,7 @@ impl Database {
|
||||||
Ok(sgfs) => {
|
Ok(sgfs) => {
|
||||||
for sgf in sgfs {
|
for sgf in sgfs {
|
||||||
match sgf {
|
match sgf {
|
||||||
Game::Go(game) => {
|
Game::Go(game) => games.push(game),
|
||||||
games.insert(GameId::new(), game);
|
|
||||||
}
|
|
||||||
Game::Unsupported(_) => {}
|
Game::Unsupported(_) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,13 +63,9 @@ impl Database {
|
||||||
self.games.len()
|
self.games.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn all_games(&self) -> impl Iterator<Item = (&GameId, &go::Game)> {
|
pub fn all_games(&self) -> impl Iterator<Item = &go::Game> {
|
||||||
self.games.iter()
|
self.games.iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self, game_id: &GameId) -> Option<&go::Game> {
|
|
||||||
self.games.get(game_id)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -2,12 +2,9 @@ use serde::{Deserialize, Serialize};
|
||||||
use sgf::go::{Game, GameResult, Win};
|
use sgf::go::{Game, GameResult, Win};
|
||||||
use typeshare::typeshare;
|
use typeshare::typeshare;
|
||||||
|
|
||||||
use crate::api::GameId;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
#[typeshare]
|
#[typeshare]
|
||||||
pub struct GamePreviewElement {
|
pub struct GamePreviewElement {
|
||||||
pub id: GameId,
|
|
||||||
pub date: String,
|
pub date: String,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub black_player: String,
|
pub black_player: String,
|
||||||
|
@ -16,7 +13,7 @@ pub struct GamePreviewElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GamePreviewElement {
|
impl GamePreviewElement {
|
||||||
pub fn new(id: &GameId, game: &Game) -> GamePreviewElement {
|
pub fn new(game: &Game) -> GamePreviewElement {
|
||||||
let black_player = match game.info.black_player {
|
let black_player = match game.info.black_player {
|
||||||
Some(ref black_player) => black_player.clone(),
|
Some(ref black_player) => black_player.clone(),
|
||||||
None => "unknown".to_owned(),
|
None => "unknown".to_owned(),
|
||||||
|
@ -58,7 +55,6 @@ impl GamePreviewElement {
|
||||||
};
|
};
|
||||||
|
|
||||||
GamePreviewElement {
|
GamePreviewElement {
|
||||||
id: id.clone(),
|
|
||||||
date: game
|
date: game
|
||||||
.info
|
.info
|
||||||
.date
|
.date
|
||||||
|
|
|
@ -26,7 +26,7 @@ pub struct Node {
|
||||||
pub children: Vec<Node>,
|
pub children: Vec<Node>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn review(game: &Game) -> GameReviewView {
|
pub fn review() -> GameReviewView {
|
||||||
GameReviewView {
|
GameReviewView {
|
||||||
black_player: "savanni".to_owned(),
|
black_player: "savanni".to_owned(),
|
||||||
white_player: "kat".to_owned(),
|
white_player: "kat".to_owned(),
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
use crate::{
|
use crate::ui::{Action, GamePreviewElement};
|
||||||
api::GameId,
|
|
||||||
ui::{Action, GamePreviewElement},
|
|
||||||
};
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sgf::go::Game;
|
use sgf::go::Game;
|
||||||
use typeshare::typeshare;
|
use typeshare::typeshare;
|
||||||
|
@ -59,7 +56,7 @@ pub struct HomeView {
|
||||||
pub start_game: Action<()>,
|
pub start_game: Action<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn home<'a>(games: impl Iterator<Item = (&'a GameId, &'a Game)>) -> HomeView {
|
pub fn home<'a>(games: impl Iterator<Item = &'a Game>) -> HomeView {
|
||||||
let black_player = PlayerElement::Hotseat(HotseatPlayerElement {
|
let black_player = PlayerElement::Hotseat(HotseatPlayerElement {
|
||||||
placeholder: Some("black player".to_owned()),
|
placeholder: Some("black player".to_owned()),
|
||||||
default_rank: None,
|
default_rank: None,
|
||||||
|
@ -73,9 +70,7 @@ pub fn home<'a>(games: impl Iterator<Item = (&'a GameId, &'a Game)>) -> HomeView
|
||||||
HomeView {
|
HomeView {
|
||||||
black_player,
|
black_player,
|
||||||
white_player,
|
white_player,
|
||||||
games: games
|
games: games.map(GamePreviewElement::new).collect(),
|
||||||
.map(|(id, game)| GamePreviewElement::new(id, game))
|
|
||||||
.collect(),
|
|
||||||
start_game: Action {
|
start_game: Action {
|
||||||
id: "start-game-action".to_owned(),
|
id: "start-game-action".to_owned(),
|
||||||
label: "New Game".to_owned(),
|
label: "New Game".to_owned(),
|
||||||
|
|
|
@ -5,7 +5,7 @@ mod elements;
|
||||||
pub use elements::{game_preview::GamePreviewElement, menu::Menu, Action, Field, Toggle};
|
pub use elements::{game_preview::GamePreviewElement, menu::Menu, Action, Field, Toggle};
|
||||||
|
|
||||||
mod game_review;
|
mod game_review;
|
||||||
pub use game_review::{review, GameReviewView, Node};
|
pub use game_review::{review, GameReviewView};
|
||||||
|
|
||||||
mod playing_field;
|
mod playing_field;
|
||||||
pub use playing_field::{playing_field, PlayingFieldView};
|
pub use playing_field::{playing_field, PlayingFieldView};
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
use crate::{
|
use crate::{ui::Board, CoreApi};
|
||||||
ui::{Board, ReviewTree},
|
|
||||||
CoreApi,
|
|
||||||
};
|
|
||||||
use glib::Object;
|
use glib::Object;
|
||||||
use gtk::{prelude::*, subclass::prelude::*};
|
use gtk::{prelude::*, subclass::prelude::*};
|
||||||
use kifu_core::ui::GameReviewView;
|
use kifu_core::ui::GameReviewView;
|
||||||
|
@ -10,7 +7,6 @@ use std::{cell::RefCell, rc::Rc};
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct GameReviewPrivate {
|
pub struct GameReviewPrivate {
|
||||||
board: Rc<RefCell<Option<Board>>>,
|
board: Rc<RefCell<Option<Board>>>,
|
||||||
tree: ReviewTree,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
|
@ -33,18 +29,6 @@ glib::wrapper! {
|
||||||
impl GameReview {
|
impl GameReview {
|
||||||
pub fn new(api: CoreApi, view: GameReviewView) -> Self {
|
pub fn new(api: CoreApi, view: GameReviewView) -> Self {
|
||||||
let s: Self = Object::builder().build();
|
let s: Self = Object::builder().build();
|
||||||
s.set_orientation(gtk::Orientation::Horizontal);
|
|
||||||
|
|
||||||
let review_area = gtk::ScrolledWindow::builder()
|
|
||||||
.hscrollbar_policy(gtk::PolicyType::Automatic)
|
|
||||||
.vscrollbar_policy(gtk::PolicyType::Automatic)
|
|
||||||
.hexpand(true)
|
|
||||||
.vexpand(true)
|
|
||||||
.build();
|
|
||||||
review_area.set_child(Some(&s.imp().tree));
|
|
||||||
s.append(&review_area);
|
|
||||||
|
|
||||||
s.imp().tree.set_tree(view.tree);
|
|
||||||
|
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use crate::{ui::GamePreview, CoreApi};
|
use crate::{ui::GamePreview, CoreApi};
|
||||||
use adw::{prelude::*, subclass::prelude::*};
|
use adw::{prelude::*, subclass::prelude::*};
|
||||||
use gio::ListModel;
|
|
||||||
use glib::Object;
|
use glib::Object;
|
||||||
use gtk::{glib, prelude::*, subclass::prelude::*};
|
use gtk::{glib, prelude::*, subclass::prelude::*};
|
||||||
use kifu_core::ui::GamePreviewElement;
|
use kifu_core::ui::GamePreviewElement;
|
||||||
|
@ -122,18 +121,8 @@ impl Library {
|
||||||
let s: Self = Object::builder().build();
|
let s: Self = Object::builder().build();
|
||||||
|
|
||||||
s.set_child(Some(&s.imp().list_view));
|
s.set_child(Some(&s.imp().list_view));
|
||||||
s.imp().list_view.connect_activate({
|
s.imp().list_view.connect_activate(move |list, row_id| {
|
||||||
let s = s.clone();
|
api.dispatch(kifu_core::CoreRequest::OpenGameReview);
|
||||||
move |_, row_id| {
|
|
||||||
let object = s.imp().model.item(row_id).unwrap();
|
|
||||||
// let list_item = object.downcast_ref::<gtk::ListItem>().unwrap();
|
|
||||||
// let game = list_item.item().and_downcast::<GameObject>().unwrap();
|
|
||||||
// let game_id = game.game().unwrap().id;
|
|
||||||
// let game = object.downcast_ref::<gtk::ListItem>()
|
|
||||||
let game = object.downcast::<GameObject>().unwrap();
|
|
||||||
let game_id = game.game().unwrap().id;
|
|
||||||
api.dispatch(kifu_core::CoreRequest::OpenGameReview(game_id));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,139 +1,30 @@
|
||||||
use adw::{prelude::*, subclass::prelude::*};
|
use adw::{prelude::*, subclass::prelude::*};
|
||||||
use cairo::Context;
|
|
||||||
use glib::Object;
|
use glib::Object;
|
||||||
use kifu_core::ui::Node;
|
use std::{cell::Cell, rc::Rc};
|
||||||
use std::{cell::RefCell, f64::consts::PI, rc::Rc};
|
|
||||||
|
|
||||||
const NODE_SIZE: f64 = 10.;
|
|
||||||
const NODE_ROW_HEIGHT: f64 = 30.;
|
|
||||||
const NODE_COLUMN_WIDTH: f64 = 30.;
|
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct ReviewTreePrivate {
|
pub struct ReviewTreePrivate {}
|
||||||
tree: Rc<RefCell<Option<Node>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
impl ObjectSubclass for ReviewTreePrivate {
|
impl ObjectSubclass for ReviewTreePrivate {
|
||||||
const NAME: &'static str = "ReviewTree";
|
const NAME: &'static str = "ReviewTree";
|
||||||
type Type = ReviewTree;
|
type Type = ReviewTree;
|
||||||
type ParentType = gtk::DrawingArea;
|
type ParentType = adw::Bin;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObjectImpl for ReviewTreePrivate {}
|
impl ObjectImpl for ReviewTreePrivate {}
|
||||||
impl WidgetImpl for ReviewTreePrivate {}
|
impl WidgetImpl for ReviewTreePrivate {}
|
||||||
impl DrawingAreaImpl for ReviewTreePrivate {}
|
impl BinImpl for ReviewTreePrivate {}
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct ReviewTree(ObjectSubclass<ReviewTreePrivate>)
|
pub struct ReviewTree(ObjectSubclass<ReviewTreePrivate>)
|
||||||
@extends gtk::DrawingArea, gtk::Widget;
|
@extends adw::Bin, gtk::Widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReviewTree {
|
impl ReviewTree {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let s: Self = Object::builder().build();
|
let s: Self = Object::builder().build();
|
||||||
|
|
||||||
s.set_draw_func({
|
|
||||||
let s = s.clone();
|
|
||||||
move |_, context, width, height| {
|
|
||||||
println!("drawing area: {} {}", width, height);
|
|
||||||
let style_context = WidgetExt::style_context(&s);
|
|
||||||
let bg = style_context.lookup_color("view_bg_color").unwrap();
|
|
||||||
let fg = style_context.lookup_color("view_fg_color").unwrap();
|
|
||||||
|
|
||||||
context.set_source_rgb(bg.red() as f64, bg.green() as f64, bg.blue() as f64);
|
|
||||||
let _ = context.paint();
|
|
||||||
|
|
||||||
if let Some(tree) = &*s.imp().tree.borrow() {
|
|
||||||
let (width, height) = max_tree_dimensions(tree);
|
|
||||||
println!("tree dimensions: {} {}", width, height);
|
|
||||||
s.set_width_request(
|
|
||||||
width as i32 * (NODE_SIZE as i32 + NODE_COLUMN_WIDTH as i32) + 20,
|
|
||||||
);
|
|
||||||
s.set_height_request(
|
|
||||||
height as i32 * (NODE_SIZE as i32 + NODE_ROW_HEIGHT as i32) + 20,
|
|
||||||
);
|
|
||||||
|
|
||||||
context.set_source_rgb(fg.red() as f64, fg.green() as f64, fg.blue() as f64);
|
|
||||||
draw_tree(&context, &tree);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_tree(&self, tree: Node) {
|
|
||||||
*self.imp().tree.borrow_mut() = Some(tree);
|
|
||||||
self.queue_draw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for ReviewTree {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn draw_node(context: &Context, x: f64, y: f64) {
|
|
||||||
context.arc(x, y, NODE_SIZE, 0., 2. * PI);
|
|
||||||
let _ = context.fill();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn draw_tree(context: &Context, tree: &Node) {
|
|
||||||
let mut row: Vec<&Node> = vec![];
|
|
||||||
let mut next_row: Vec<&Node> = vec![];
|
|
||||||
let mut width: Vec<usize> = vec![];
|
|
||||||
|
|
||||||
let mut x = 0;
|
|
||||||
let mut y = 0;
|
|
||||||
|
|
||||||
row.push(tree);
|
|
||||||
width.push(1);
|
|
||||||
|
|
||||||
while row.len() != 0 {
|
|
||||||
for node in row.into_iter() {
|
|
||||||
draw_node(
|
|
||||||
context,
|
|
||||||
10. + (x as f64) * (NODE_SIZE + NODE_COLUMN_WIDTH),
|
|
||||||
10. + (y as f64) * (NODE_SIZE + NODE_ROW_HEIGHT),
|
|
||||||
);
|
|
||||||
next_row.append(&mut node.children.iter().map(|n| n).collect::<Vec<&Node>>());
|
|
||||||
x = x + 1;
|
|
||||||
}
|
|
||||||
x = 0;
|
|
||||||
y = y + 1;
|
|
||||||
row = next_row;
|
|
||||||
next_row = vec![];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn max_tree_dimensions(tree: &Node) -> (usize, usize) {
|
|
||||||
let mut row: Vec<&Node> = vec![];
|
|
||||||
let mut next_row: Vec<&Node> = vec![];
|
|
||||||
let mut width: Vec<usize> = vec![];
|
|
||||||
|
|
||||||
row.push(tree);
|
|
||||||
width.push(1);
|
|
||||||
|
|
||||||
while row.len() != 0 {
|
|
||||||
println!("new row");
|
|
||||||
for node in row.into_iter() {
|
|
||||||
println!(
|
|
||||||
"{:?} {:?} {}",
|
|
||||||
node.color,
|
|
||||||
node.position,
|
|
||||||
node.children.len()
|
|
||||||
);
|
|
||||||
next_row.append(&mut node.children.iter().map(|n| n).collect::<Vec<&Node>>());
|
|
||||||
}
|
|
||||||
width.push(next_row.len());
|
|
||||||
row = next_row;
|
|
||||||
next_row = vec![];
|
|
||||||
}
|
|
||||||
|
|
||||||
(
|
|
||||||
width.iter().fold(0, |a, b| if a > *b { a } else { *b }),
|
|
||||||
width.len(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,3 @@ nom = { version = "7" }
|
||||||
serde = { version = "1", features = [ "derive" ] }
|
serde = { version = "1", features = [ "derive" ] }
|
||||||
thiserror = { version = "1"}
|
thiserror = { version = "1"}
|
||||||
typeshare = { version = "1" }
|
typeshare = { version = "1" }
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
cool_asserts = { version = "2" }
|
|
||||||
|
|
178
sgf/src/go.rs
178
sgf/src/go.rs
|
@ -74,7 +74,6 @@ use crate::{
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::ops::Deref;
|
|
||||||
use typeshare::typeshare;
|
use typeshare::typeshare;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
@ -85,18 +84,11 @@ pub struct Game {
|
||||||
pub tree: Tree,
|
pub tree: Tree,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for Game {
|
|
||||||
type Target = Tree;
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.tree
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<Tree> for Game {
|
impl TryFrom<Tree> for Game {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn try_from(tree: Tree) -> Result<Self, Self::Error> {
|
fn try_from(tree: Tree) -> Result<Self, Self::Error> {
|
||||||
let board_size = match tree.root.find_prop("SZ") {
|
let board_size = match tree.sequence[0].find_prop("SZ") {
|
||||||
Some(prop) => Size::try_from(prop.values[0].as_str())?,
|
Some(prop) => Size::try_from(prop.values[0].as_str())?,
|
||||||
None => Size {
|
None => Size {
|
||||||
width: 19,
|
width: 19,
|
||||||
|
@ -104,37 +96,40 @@ impl TryFrom<Tree> for Game {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
let mut info = GameInfo::default();
|
let mut info = GameInfo::default();
|
||||||
info.app_name = tree.root.find_prop("AP").map(|prop| prop.values[0].clone());
|
info.app_name = tree.sequence[0]
|
||||||
|
.find_prop("AP")
|
||||||
|
.map(|prop| prop.values[0].clone());
|
||||||
|
|
||||||
info.game_name = tree.root.find_prop("GN").map(|prop| prop.values[0].clone());
|
info.game_name = tree.sequence[0]
|
||||||
|
.find_prop("GN")
|
||||||
|
.map(|prop| prop.values[0].clone());
|
||||||
|
|
||||||
info.black_player = tree.root.find_prop("PB").map(|prop| prop.values.join(", "));
|
info.black_player = tree.sequence[0]
|
||||||
|
.find_prop("PB")
|
||||||
|
.map(|prop| prop.values.join(", "));
|
||||||
|
|
||||||
info.black_rank = tree
|
info.black_rank = tree.sequence[0]
|
||||||
.root
|
|
||||||
.find_prop("BR")
|
.find_prop("BR")
|
||||||
.and_then(|prop| Rank::try_from(prop.values[0].as_str()).ok());
|
.and_then(|prop| Rank::try_from(prop.values[0].as_str()).ok());
|
||||||
|
|
||||||
info.white_player = tree.root.find_prop("PW").map(|prop| prop.values.join(", "));
|
info.white_player = tree.sequence[0]
|
||||||
|
.find_prop("PW")
|
||||||
|
.map(|prop| prop.values.join(", "));
|
||||||
|
|
||||||
info.white_rank = tree
|
info.white_rank = tree.sequence[0]
|
||||||
.root
|
|
||||||
.find_prop("WR")
|
.find_prop("WR")
|
||||||
.and_then(|prop| Rank::try_from(prop.values[0].as_str()).ok());
|
.and_then(|prop| Rank::try_from(prop.values[0].as_str()).ok());
|
||||||
|
|
||||||
info.result = tree
|
info.result = tree.sequence[0]
|
||||||
.root
|
|
||||||
.find_prop("RE")
|
.find_prop("RE")
|
||||||
.and_then(|prop| GameResult::try_from(prop.values[0].as_str()).ok());
|
.and_then(|prop| GameResult::try_from(prop.values[0].as_str()).ok());
|
||||||
|
|
||||||
info.time_limits = tree
|
info.time_limits = tree.sequence[0]
|
||||||
.root
|
|
||||||
.find_prop("TM")
|
.find_prop("TM")
|
||||||
.and_then(|prop| prop.values[0].parse::<u64>().ok())
|
.and_then(|prop| prop.values[0].parse::<u64>().ok())
|
||||||
.and_then(|seconds| Some(std::time::Duration::from_secs(seconds)));
|
.and_then(|seconds| Some(std::time::Duration::from_secs(seconds)));
|
||||||
|
|
||||||
info.date = tree
|
info.date = tree.sequence[0]
|
||||||
.root
|
|
||||||
.find_prop("DT")
|
.find_prop("DT")
|
||||||
.and_then(|prop| {
|
.and_then(|prop| {
|
||||||
let v = prop
|
let v = prop
|
||||||
|
@ -154,13 +149,21 @@ impl TryFrom<Tree> for Game {
|
||||||
})
|
})
|
||||||
.unwrap_or(vec![]);
|
.unwrap_or(vec![]);
|
||||||
|
|
||||||
info.event = tree.root.find_prop("EV").map(|prop| prop.values.join(", "));
|
info.event = tree.sequence[0]
|
||||||
|
.find_prop("EV")
|
||||||
|
.map(|prop| prop.values.join(", "));
|
||||||
|
|
||||||
info.round = tree.root.find_prop("RO").map(|prop| prop.values.join(", "));
|
info.round = tree.sequence[0]
|
||||||
|
.find_prop("RO")
|
||||||
|
.map(|prop| prop.values.join(", "));
|
||||||
|
|
||||||
info.source = tree.root.find_prop("SO").map(|prop| prop.values.join(", "));
|
info.source = tree.sequence[0]
|
||||||
|
.find_prop("SO")
|
||||||
|
.map(|prop| prop.values.join(", "));
|
||||||
|
|
||||||
info.game_keeper = tree.root.find_prop("US").map(|prop| prop.values.join(", "));
|
info.game_keeper = tree.sequence[0]
|
||||||
|
.find_prop("US")
|
||||||
|
.map(|prop| prop.values.join(", "));
|
||||||
|
|
||||||
Ok(Game {
|
Ok(Game {
|
||||||
board_size,
|
board_size,
|
||||||
|
@ -304,7 +307,7 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
date::Date,
|
date::Date,
|
||||||
tree::{parse_collection, Property, Size},
|
tree::{parse_collection, Size},
|
||||||
};
|
};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
@ -387,123 +390,4 @@ mod tests {
|
||||||
assert_eq!(tree.info.game_keeper, Some("Arno Hollosi".to_owned()));
|
assert_eq!(tree.info.game_keeper, Some("Arno Hollosi".to_owned()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_presents_the_mainline_of_game_without_branches() {
|
|
||||||
with_file(
|
|
||||||
std::path::Path::new("test_data/2020 USGO DDK, Round 1.sgf"),
|
|
||||||
|trees| {
|
|
||||||
assert_eq!(trees.len(), 1);
|
|
||||||
let tree = &trees[0];
|
|
||||||
|
|
||||||
let node = &tree.root;
|
|
||||||
assert_eq!(node.properties.len(), 16);
|
|
||||||
let expected_properties = vec![
|
|
||||||
Property {
|
|
||||||
ident: "GM".to_owned(),
|
|
||||||
values: vec!["1".to_owned()],
|
|
||||||
},
|
|
||||||
Property {
|
|
||||||
ident: "FF".to_owned(),
|
|
||||||
values: vec!["4".to_owned()],
|
|
||||||
},
|
|
||||||
Property {
|
|
||||||
ident: "CA".to_owned(),
|
|
||||||
values: vec!["UTF-8".to_owned()],
|
|
||||||
},
|
|
||||||
Property {
|
|
||||||
ident: "AP".to_owned(),
|
|
||||||
values: vec!["CGoban:3".to_owned()],
|
|
||||||
},
|
|
||||||
Property {
|
|
||||||
ident: "ST".to_owned(),
|
|
||||||
values: vec!["2".to_owned()],
|
|
||||||
},
|
|
||||||
Property {
|
|
||||||
ident: "RU".to_owned(),
|
|
||||||
values: vec!["AGA".to_owned()],
|
|
||||||
},
|
|
||||||
Property {
|
|
||||||
ident: "SZ".to_owned(),
|
|
||||||
values: vec!["19".to_owned()],
|
|
||||||
},
|
|
||||||
Property {
|
|
||||||
ident: "KM".to_owned(),
|
|
||||||
values: vec!["7.50".to_owned()],
|
|
||||||
},
|
|
||||||
Property {
|
|
||||||
ident: "TM".to_owned(),
|
|
||||||
values: vec!["1800".to_owned()],
|
|
||||||
},
|
|
||||||
Property {
|
|
||||||
ident: "OT".to_owned(),
|
|
||||||
values: vec!["5x30 byo-yomi".to_owned()],
|
|
||||||
},
|
|
||||||
Property {
|
|
||||||
ident: "PW".to_owned(),
|
|
||||||
values: vec!["Geckoz".to_owned()],
|
|
||||||
},
|
|
||||||
Property {
|
|
||||||
ident: "PB".to_owned(),
|
|
||||||
values: vec!["savanni".to_owned()],
|
|
||||||
},
|
|
||||||
Property {
|
|
||||||
ident: "BR".to_owned(),
|
|
||||||
values: vec!["23k".to_owned()],
|
|
||||||
},
|
|
||||||
Property {
|
|
||||||
ident: "DT".to_owned(),
|
|
||||||
values: vec!["2020-08-05".to_owned()],
|
|
||||||
},
|
|
||||||
Property {
|
|
||||||
ident: "PC".to_owned(),
|
|
||||||
values: vec!["The KGS Go Server at http://www.gokgs.com/".to_owned()],
|
|
||||||
},
|
|
||||||
Property {
|
|
||||||
ident: "RE".to_owned(),
|
|
||||||
values: vec!["W+17.50".to_owned()],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
for i in 0..16 {
|
|
||||||
assert_eq!(node.properties[i], expected_properties[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
let node = node.next().unwrap();
|
|
||||||
let expected_properties = vec![
|
|
||||||
Property {
|
|
||||||
ident: "B".to_owned(),
|
|
||||||
values: vec!["pp".to_owned()],
|
|
||||||
},
|
|
||||||
Property {
|
|
||||||
ident: "BL".to_owned(),
|
|
||||||
values: vec!["1795.449".to_owned()],
|
|
||||||
},
|
|
||||||
Property {
|
|
||||||
ident: "C".to_owned(),
|
|
||||||
values: vec!["Geckoz [?]: Good game\nsavanni [23k?]: There we go! This UI is... tough.\nsavanni [23k?]: Have fun! Talk to you at the end.\nGeckoz [?]: Yeah, OGS is much better; I'm a UX professional\n".to_owned()],
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
for i in 0..3 {
|
|
||||||
assert_eq!(node.properties[i], expected_properties[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
let node = node.next().unwrap();
|
|
||||||
let expected_properties = vec![
|
|
||||||
Property {
|
|
||||||
ident: "W".to_owned(),
|
|
||||||
values: vec!["dp".to_owned()],
|
|
||||||
},
|
|
||||||
Property {
|
|
||||||
ident: "WL".to_owned(),
|
|
||||||
values: vec!["1765.099".to_owned()],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
for i in 0..2 {
|
|
||||||
assert_eq!(node.properties[i], expected_properties[i]);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ pub fn parse_sgf(input: &str) -> Result<Vec<Game>, Error> {
|
||||||
let (_, trees) = parse_collection::<nom::error::VerboseError<&str>>(input)?;
|
let (_, trees) = parse_collection::<nom::error::VerboseError<&str>>(input)?;
|
||||||
Ok(trees
|
Ok(trees
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|t| match t.root.find_prop("GM") {
|
.map(|t| match t.sequence[0].find_prop("GM") {
|
||||||
Some(prop) if prop.values == vec!["1".to_owned()] => {
|
Some(prop) if prop.values == vec!["1".to_owned()] => {
|
||||||
Game::Go(go::Game::try_from(t).expect("properly structured game tree"))
|
Game::Go(go::Game::try_from(t).expect("properly structured game tree"))
|
||||||
}
|
}
|
||||||
|
|
277
sgf/src/tree.rs
277
sgf/src/tree.rs
|
@ -5,6 +5,7 @@ use nom::{
|
||||||
character::complete::{alpha1, digit1, multispace0, multispace1, none_of},
|
character::complete::{alpha1, digit1, multispace0, multispace1, none_of},
|
||||||
combinator::{opt, value},
|
combinator::{opt, value},
|
||||||
multi::{many0, many1, separated_list1},
|
multi::{many0, many1, separated_list1},
|
||||||
|
sequence::delimited,
|
||||||
IResult,
|
IResult,
|
||||||
};
|
};
|
||||||
use std::num::ParseIntError;
|
use std::num::ParseIntError;
|
||||||
|
@ -53,19 +54,29 @@ impl TryFrom<&str> for Size {
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct Tree {
|
pub struct Tree {
|
||||||
pub root: Node,
|
pub sequence: Vec<Node>,
|
||||||
|
pub sub_sequences: Vec<Tree>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToString for Tree {
|
impl ToString for Tree {
|
||||||
fn to_string(&self) -> String {
|
fn to_string(&self) -> String {
|
||||||
format!("({})", self.root.to_string())
|
let sequence = self
|
||||||
|
.sequence
|
||||||
|
.iter()
|
||||||
|
.map(|node| node.to_string())
|
||||||
|
.collect::<String>();
|
||||||
|
let subsequences = self
|
||||||
|
.sub_sequences
|
||||||
|
.iter()
|
||||||
|
.map(|seq| seq.to_string())
|
||||||
|
.collect::<String>();
|
||||||
|
format!("({}{})", sequence, subsequences)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct Node {
|
pub struct Node {
|
||||||
pub properties: Vec<Property>,
|
pub properties: Vec<Property>,
|
||||||
pub next: Vec<Node>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToString for Node {
|
impl ToString for Node {
|
||||||
|
@ -75,21 +86,7 @@ impl ToString for Node {
|
||||||
.iter()
|
.iter()
|
||||||
.map(|prop| prop.to_string())
|
.map(|prop| prop.to_string())
|
||||||
.collect::<String>();
|
.collect::<String>();
|
||||||
|
format!(";{}", props)
|
||||||
let next = if self.next.len() == 1 {
|
|
||||||
self.next
|
|
||||||
.iter()
|
|
||||||
.map(|node| node.to_string())
|
|
||||||
.collect::<Vec<String>>()
|
|
||||||
.join("")
|
|
||||||
} else {
|
|
||||||
self.next
|
|
||||||
.iter()
|
|
||||||
.map(|node| format!("({})", node.to_string()))
|
|
||||||
.collect::<Vec<String>>()
|
|
||||||
.join("")
|
|
||||||
};
|
|
||||||
format!(";{}{}", props, next)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,10 +97,6 @@ impl Node {
|
||||||
.find(|prop| prop.ident == ident)
|
.find(|prop| prop.ident == ident)
|
||||||
.cloned()
|
.cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next<'a>(&'a self) -> Option<&'a Node> {
|
|
||||||
self.next.get(0)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
@ -126,40 +119,40 @@ impl ToString for Property {
|
||||||
pub fn parse_collection<'a, E: nom::error::ParseError<&'a str>>(
|
pub fn parse_collection<'a, E: nom::error::ParseError<&'a str>>(
|
||||||
input: &'a str,
|
input: &'a str,
|
||||||
) -> IResult<&'a str, Vec<Tree>, E> {
|
) -> IResult<&'a str, Vec<Tree>, E> {
|
||||||
let (input, roots) = separated_list1(multispace1, parse_tree)(input)?;
|
separated_list1(multispace1, parse_tree)(input)
|
||||||
let trees = roots
|
|
||||||
.into_iter()
|
|
||||||
.map(|root| Tree { root })
|
|
||||||
.collect::<Vec<Tree>>();
|
|
||||||
|
|
||||||
Ok((input, trees))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// note: must preserve unknown properties
|
// note: must preserve unknown properties
|
||||||
// note: must fix or preserve illegally formatted game-info properties
|
// note: must fix or preserve illegally formatted game-info properties
|
||||||
// note: must correct or delete illegally foramtted properties, but display a warning
|
// note: must correct or delete illegally foramtted properties, but display a warning
|
||||||
fn parse_tree<'a, E: nom::error::ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Node, E> {
|
fn parse_tree<'a, E: nom::error::ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Tree, E> {
|
||||||
let (input, _) = multispace0(input)?;
|
let (input, _) = multispace0(input)?;
|
||||||
let (input, _) = tag("(")(input)?;
|
delimited(tag("("), parse_sequence, tag(")"))(input)
|
||||||
let (input, node) = parse_node(input)?;
|
}
|
||||||
let (input, _) = multispace0(input)?;
|
|
||||||
let (input, _) = tag(")")(input)?;
|
|
||||||
|
|
||||||
Ok((input, node))
|
fn parse_sequence<'a, E: nom::error::ParseError<&'a str>>(
|
||||||
|
input: &'a str,
|
||||||
|
) -> IResult<&'a str, Tree, E> {
|
||||||
|
let (input, _) = multispace0(input)?;
|
||||||
|
let (input, nodes) = many1(parse_node)(input)?;
|
||||||
|
let (input, _) = multispace0(input)?;
|
||||||
|
let (input, sub_sequences) = many0(parse_tree)(input)?;
|
||||||
|
let (input, _) = multispace0(input)?;
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
input,
|
||||||
|
Tree {
|
||||||
|
sequence: nodes,
|
||||||
|
sub_sequences,
|
||||||
|
},
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_node<'a, E: nom::error::ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Node, E> {
|
fn parse_node<'a, E: nom::error::ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Node, E> {
|
||||||
let (input, _) = multispace0(input)?;
|
let (input, _) = multispace0(input)?;
|
||||||
let (input, _) = opt(tag(";"))(input)?;
|
let (input, _) = tag(";")(input)?;
|
||||||
let (input, properties) = many1(parse_property)(input)?;
|
let (input, properties) = many1(parse_property)(input)?;
|
||||||
|
Ok((input, Node { properties }))
|
||||||
let (input, next) = opt(parse_node)(input)?;
|
|
||||||
let (input, mut next_seq) = many0(parse_tree)(input)?;
|
|
||||||
|
|
||||||
let mut next = next.map(|n| vec![n]).unwrap_or(vec![]);
|
|
||||||
next.append(&mut next_seq);
|
|
||||||
|
|
||||||
Ok((input, Node { properties, next }))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_property<'a, E: nom::error::ParseError<&'a str>>(
|
fn parse_property<'a, E: nom::error::ParseError<&'a str>>(
|
||||||
|
@ -226,6 +219,8 @@ pub fn parse_size<'a, E: nom::error::ParseError<&'a str>>(
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
use std::{fs::File, io::Read};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
const EXAMPLE: &'static str = "(;FF[4]C[root](;C[a];C[b](;C[c])
|
const EXAMPLE: &'static str = "(;FF[4]C[root](;C[a];C[b](;C[c])
|
||||||
|
@ -264,8 +259,7 @@ mod test {
|
||||||
properties: vec![Property {
|
properties: vec![Property {
|
||||||
ident: "B".to_owned(),
|
ident: "B".to_owned(),
|
||||||
values: vec!["ab".to_owned()]
|
values: vec!["ab".to_owned()]
|
||||||
}],
|
}]
|
||||||
next: vec![]
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -279,25 +273,6 @@ mod test {
|
||||||
properties: vec![Property {
|
properties: vec![Property {
|
||||||
ident: "B".to_owned(),
|
ident: "B".to_owned(),
|
||||||
values: vec!["ab".to_owned()]
|
values: vec!["ab".to_owned()]
|
||||||
}],
|
|
||||||
next: vec![Node {
|
|
||||||
properties: vec![Property {
|
|
||||||
ident: "W".to_owned(),
|
|
||||||
values: vec!["dp".to_owned()]
|
|
||||||
}],
|
|
||||||
next: vec![Node {
|
|
||||||
properties: vec![
|
|
||||||
Property {
|
|
||||||
ident: "B".to_owned(),
|
|
||||||
values: vec!["pq".to_owned()]
|
|
||||||
},
|
|
||||||
Property {
|
|
||||||
ident: "C".to_owned(),
|
|
||||||
values: vec!["some comments".to_owned()]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
next: vec![],
|
|
||||||
}]
|
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -311,17 +286,21 @@ mod test {
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
sequence,
|
sequence,
|
||||||
|
Tree {
|
||||||
|
sequence: vec![
|
||||||
Node {
|
Node {
|
||||||
properties: vec![Property {
|
properties: vec![Property {
|
||||||
ident: "B".to_owned(),
|
ident: "B".to_owned(),
|
||||||
values: vec!["ab".to_owned()]
|
values: vec!["ab".to_owned()]
|
||||||
}],
|
}]
|
||||||
next: vec![Node {
|
},
|
||||||
|
Node {
|
||||||
properties: vec![Property {
|
properties: vec![Property {
|
||||||
ident: "W".to_owned(),
|
ident: "W".to_owned(),
|
||||||
values: vec!["dp".to_owned()]
|
values: vec!["dp".to_owned()]
|
||||||
}],
|
}]
|
||||||
next: vec![Node {
|
},
|
||||||
|
Node {
|
||||||
properties: vec![
|
properties: vec![
|
||||||
Property {
|
Property {
|
||||||
ident: "B".to_owned(),
|
ident: "B".to_owned(),
|
||||||
|
@ -331,158 +310,114 @@ mod test {
|
||||||
ident: "C".to_owned(),
|
ident: "C".to_owned(),
|
||||||
values: vec!["some comments".to_owned()]
|
values: vec!["some comments".to_owned()]
|
||||||
}
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
],
|
],
|
||||||
next: vec![],
|
sub_sequences: vec![],
|
||||||
}]
|
}
|
||||||
}],
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn it_can_parse_a_branching_sequence() {
|
fn it_can_parse_a_sequence_with_subsequences() {
|
||||||
let text = "(;C[a];C[b](;C[c])(;C[d];C[e]))";
|
let text = "(;C[a];C[b](;C[c])(;C[d];C[e]))";
|
||||||
let (_, tree) = parse_tree::<nom::error::VerboseError<&str>>(text).unwrap();
|
let (_, sequence) = parse_tree::<nom::error::VerboseError<&str>>(text).unwrap();
|
||||||
|
|
||||||
let expected = Node {
|
let main_sequence = vec![
|
||||||
|
Node {
|
||||||
properties: vec![Property {
|
properties: vec![Property {
|
||||||
ident: "C".to_owned(),
|
ident: "C".to_owned(),
|
||||||
values: vec!["a".to_owned()],
|
values: vec!["a".to_owned()],
|
||||||
}],
|
}],
|
||||||
next: vec![Node {
|
},
|
||||||
|
Node {
|
||||||
properties: vec![Property {
|
properties: vec![Property {
|
||||||
ident: "C".to_owned(),
|
ident: "C".to_owned(),
|
||||||
values: vec!["b".to_owned()],
|
values: vec!["b".to_owned()],
|
||||||
}],
|
}],
|
||||||
next: vec![
|
},
|
||||||
Node {
|
];
|
||||||
|
let subsequence_1 = Tree {
|
||||||
|
sequence: vec![Node {
|
||||||
properties: vec![Property {
|
properties: vec![Property {
|
||||||
ident: "C".to_owned(),
|
ident: "C".to_owned(),
|
||||||
values: vec!["c".to_owned()],
|
values: vec!["c".to_owned()],
|
||||||
}],
|
}],
|
||||||
next: vec![],
|
}],
|
||||||
},
|
sub_sequences: vec![],
|
||||||
|
};
|
||||||
|
let subsequence_2 = Tree {
|
||||||
|
sequence: vec![
|
||||||
Node {
|
Node {
|
||||||
properties: vec![Property {
|
properties: vec![Property {
|
||||||
ident: "C".to_owned(),
|
ident: "C".to_owned(),
|
||||||
values: vec!["d".to_owned()],
|
values: vec!["d".to_owned()],
|
||||||
}],
|
}],
|
||||||
next: vec![Node {
|
},
|
||||||
|
Node {
|
||||||
properties: vec![Property {
|
properties: vec![Property {
|
||||||
ident: "C".to_owned(),
|
ident: "C".to_owned(),
|
||||||
values: vec!["e".to_owned()],
|
values: vec!["e".to_owned()],
|
||||||
}],
|
}],
|
||||||
next: vec![],
|
|
||||||
}],
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}],
|
sub_sequences: vec![],
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(tree, expected);
|
assert_eq!(
|
||||||
|
sequence,
|
||||||
|
Tree {
|
||||||
|
sequence: main_sequence,
|
||||||
|
sub_sequences: vec![subsequence_1, subsequence_2],
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn it_can_parse_example_1() {
|
fn it_can_parse_example_1() {
|
||||||
let (_, tree) = parse_tree::<nom::error::VerboseError<&str>>(EXAMPLE).unwrap();
|
let (_, ex_tree) = parse_tree::<nom::error::VerboseError<&str>>(EXAMPLE).unwrap();
|
||||||
|
assert_eq!(ex_tree.sequence.len(), 1);
|
||||||
|
|
||||||
let j = Node {
|
assert_eq!(ex_tree.sequence[0].properties.len(), 2);
|
||||||
properties: vec![Property {
|
assert_eq!(
|
||||||
ident: "C".to_owned(),
|
ex_tree.sequence[0].properties[0],
|
||||||
values: vec!["j".to_owned()],
|
|
||||||
}],
|
|
||||||
next: vec![],
|
|
||||||
};
|
|
||||||
let i = Node {
|
|
||||||
properties: vec![Property {
|
|
||||||
ident: "C".to_owned(),
|
|
||||||
values: vec!["i".to_owned()],
|
|
||||||
}],
|
|
||||||
next: vec![],
|
|
||||||
};
|
|
||||||
let h = Node {
|
|
||||||
properties: vec![Property {
|
|
||||||
ident: "C".to_owned(),
|
|
||||||
values: vec!["h".to_owned()],
|
|
||||||
}],
|
|
||||||
next: vec![i],
|
|
||||||
};
|
|
||||||
let g = Node {
|
|
||||||
properties: vec![Property {
|
|
||||||
ident: "C".to_owned(),
|
|
||||||
values: vec!["g".to_owned()],
|
|
||||||
}],
|
|
||||||
next: vec![h],
|
|
||||||
};
|
|
||||||
let f = Node {
|
|
||||||
properties: vec![Property {
|
|
||||||
ident: "C".to_owned(),
|
|
||||||
values: vec!["f".to_owned()],
|
|
||||||
}],
|
|
||||||
next: vec![g, j],
|
|
||||||
};
|
|
||||||
let e = Node {
|
|
||||||
properties: vec![Property {
|
|
||||||
ident: "C".to_owned(),
|
|
||||||
values: vec!["e".to_owned()],
|
|
||||||
}],
|
|
||||||
next: vec![],
|
|
||||||
};
|
|
||||||
let d = Node {
|
|
||||||
properties: vec![Property {
|
|
||||||
ident: "C".to_owned(),
|
|
||||||
values: vec!["d".to_owned()],
|
|
||||||
}],
|
|
||||||
next: vec![e],
|
|
||||||
};
|
|
||||||
let c = Node {
|
|
||||||
properties: vec![Property {
|
|
||||||
ident: "C".to_owned(),
|
|
||||||
values: vec!["c".to_owned()],
|
|
||||||
}],
|
|
||||||
next: vec![],
|
|
||||||
};
|
|
||||||
let b = Node {
|
|
||||||
properties: vec![Property {
|
|
||||||
ident: "C".to_owned(),
|
|
||||||
values: vec!["b".to_owned()],
|
|
||||||
}],
|
|
||||||
next: vec![c, d],
|
|
||||||
};
|
|
||||||
let a = Node {
|
|
||||||
properties: vec![Property {
|
|
||||||
ident: "C".to_owned(),
|
|
||||||
values: vec!["a".to_owned()],
|
|
||||||
}],
|
|
||||||
next: vec![b],
|
|
||||||
};
|
|
||||||
let expected = Node {
|
|
||||||
properties: vec![
|
|
||||||
Property {
|
Property {
|
||||||
ident: "FF".to_owned(),
|
ident: "FF".to_owned(),
|
||||||
values: vec!["4".to_owned()],
|
values: vec!["4".to_owned()]
|
||||||
},
|
}
|
||||||
Property {
|
);
|
||||||
ident: "C".to_owned(),
|
assert_eq!(ex_tree.sub_sequences.len(), 2);
|
||||||
values: vec!["root".to_owned()],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
next: vec![a, f],
|
|
||||||
};
|
|
||||||
|
|
||||||
assert_eq!(tree, expected);
|
assert_eq!(ex_tree.sub_sequences[0].sequence.len(), 2);
|
||||||
|
assert_eq!(
|
||||||
|
ex_tree.sub_sequences[0].sequence,
|
||||||
|
vec![
|
||||||
|
Node {
|
||||||
|
properties: vec![Property {
|
||||||
|
ident: "C".to_owned(),
|
||||||
|
values: vec!["a".to_owned()]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
Node {
|
||||||
|
properties: vec![Property {
|
||||||
|
ident: "C".to_owned(),
|
||||||
|
values: vec!["b".to_owned()]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
);
|
||||||
|
assert_eq!(ex_tree.sub_sequences[0].sub_sequences.len(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn it_can_regenerate_the_tree() {
|
fn it_can_regenerate_the_tree() {
|
||||||
let (_, tree1) = parse_tree::<nom::error::VerboseError<&str>>(EXAMPLE).unwrap();
|
let (_, tree1) = parse_tree::<nom::error::VerboseError<&str>>(EXAMPLE).unwrap();
|
||||||
let tree1 = Tree { root: tree1 };
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tree1.to_string(),
|
tree1.to_string(),
|
||||||
"(;FF[4]C[root](;C[a];C[b](;C[c])(;C[d];C[e]))(;C[f](;C[g];C[h];C[i])(;C[j])))"
|
"(;FF[4]C[root](;C[a];C[b](;C[c])(;C[d];C[e]))(;C[f](;C[g];C[h];C[i])(;C[j])))"
|
||||||
);
|
);
|
||||||
let (_, tree2) = parse_tree::<nom::error::VerboseError<&str>>(&tree1.to_string()).unwrap();
|
let (_, tree2) = parse_tree::<nom::error::VerboseError<&str>>(&tree1.to_string()).unwrap();
|
||||||
assert_eq!(tree1, Tree { root: tree2 });
|
assert_eq!(tree1, tree2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Reference in New Issue