mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
Use ffizz_header to generate taskchampion.h
This commit is contained in:
parent
989a330e46
commit
75e10676ce
20 changed files with 1881 additions and 1281 deletions
140
Cargo.lock
generated
140
Cargo.lock
generated
|
@ -301,17 +301,6 @@ version = "1.0.66"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6"
|
checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "atty"
|
|
||||||
version = "0.2.14"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
|
||||||
dependencies = [
|
|
||||||
"hermit-abi 0.1.19",
|
|
||||||
"libc",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
@ -408,25 +397,6 @@ dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cbindgen"
|
|
||||||
version = "0.24.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a6358dedf60f4d9b8db43ad187391afe959746101346fe51bb978126bec61dfb"
|
|
||||||
dependencies = [
|
|
||||||
"clap 3.2.22",
|
|
||||||
"heck",
|
|
||||||
"indexmap",
|
|
||||||
"log",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
"syn",
|
|
||||||
"tempfile",
|
|
||||||
"toml",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.73"
|
version = "1.0.73"
|
||||||
|
@ -458,21 +428,6 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "clap"
|
|
||||||
version = "3.2.22"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "86447ad904c7fb335a790c9d7fe3d0d971dc523b8ccd1561a520de9a85302750"
|
|
||||||
dependencies = [
|
|
||||||
"atty",
|
|
||||||
"bitflags 1.3.2",
|
|
||||||
"clap_lex 0.2.2",
|
|
||||||
"indexmap",
|
|
||||||
"strsim",
|
|
||||||
"termcolor",
|
|
||||||
"textwrap",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.3.0"
|
version = "4.3.0"
|
||||||
|
@ -491,19 +446,10 @@ dependencies = [
|
||||||
"anstream",
|
"anstream",
|
||||||
"anstyle",
|
"anstyle",
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"clap_lex 0.5.0",
|
"clap_lex",
|
||||||
"strsim",
|
"strsim",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "clap_lex"
|
|
||||||
version = "0.2.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5538cd660450ebeb4234cfecf8f2284b844ffc4c50531e66d584ad5b91293613"
|
|
||||||
dependencies = [
|
|
||||||
"os_str_bytes",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_lex"
|
name = "clap_lex"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
|
@ -606,6 +552,12 @@ dependencies = [
|
||||||
"crypto-common",
|
"crypto-common",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "encoding_rs"
|
name = "encoding_rs"
|
||||||
version = "0.8.31"
|
version = "0.8.31"
|
||||||
|
@ -670,6 +622,29 @@ dependencies = [
|
||||||
"instant",
|
"instant",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ffizz-header"
|
||||||
|
version = "0.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6a6b3ae8dccc2b5edfc7805a0c26cc776ae521fd5f6fdd693520e130abcdce06"
|
||||||
|
dependencies = [
|
||||||
|
"ffizz-macros",
|
||||||
|
"itertools",
|
||||||
|
"linkme",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ffizz-macros"
|
||||||
|
version = "0.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "56603703fdb7bcae099f7212b9afb83f0d057236e42d87c894ba6b34ad77ac18"
|
||||||
|
dependencies = [
|
||||||
|
"itertools",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flate2"
|
name = "flate2"
|
||||||
version = "1.0.24"
|
version = "1.0.24"
|
||||||
|
@ -990,6 +965,15 @@ dependencies = [
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itertools"
|
||||||
|
version = "0.10.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
|
@ -1049,6 +1033,26 @@ dependencies = [
|
||||||
"vcpkg",
|
"vcpkg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linkme"
|
||||||
|
version = "0.3.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cfc2b30967da1bcca8f15aa741f2b949a315ef0eabd0ef630a5a0643d7a45260"
|
||||||
|
dependencies = [
|
||||||
|
"linkme-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linkme-impl"
|
||||||
|
version = "0.3.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a440f823b734f5a90d7cc2850a2254611092e88fa13fb1948556858ce2d35d2a"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linux-raw-sys"
|
name = "linux-raw-sys"
|
||||||
version = "0.3.8"
|
version = "0.3.8"
|
||||||
|
@ -1167,12 +1171,6 @@ version = "1.13.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e"
|
checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "os_str_bytes"
|
|
||||||
version = "6.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "output_vt100"
|
name = "output_vt100"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
|
@ -1673,6 +1671,7 @@ name = "taskchampion-lib"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"ffizz-header",
|
||||||
"libc",
|
"libc",
|
||||||
"pretty_assertions",
|
"pretty_assertions",
|
||||||
"taskchampion",
|
"taskchampion",
|
||||||
|
@ -1686,7 +1685,7 @@ dependencies = [
|
||||||
"actix-web",
|
"actix-web",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap 4.3.0",
|
"clap",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"futures",
|
"futures",
|
||||||
"log",
|
"log",
|
||||||
|
@ -1722,12 +1721,6 @@ dependencies = [
|
||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "textwrap"
|
|
||||||
version = "0.15.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "949517c0cf1bf4ee812e2e07e08ab448e3ae0d23472aee8a06c985f0c8815b16"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.37"
|
version = "1.0.37"
|
||||||
|
@ -1831,15 +1824,6 @@ dependencies = [
|
||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "toml"
|
|
||||||
version = "0.5.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
|
|
||||||
dependencies = [
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing"
|
name = "tracing"
|
||||||
version = "0.1.34"
|
version = "0.1.34"
|
||||||
|
@ -2212,7 +2196,7 @@ name = "xtask"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cbindgen",
|
"taskchampion-lib",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
87
src/tc/rust/Cargo.lock
generated
87
src/tc/rust/Cargo.lock
generated
|
@ -161,6 +161,12 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fallible-iterator"
|
name = "fallible-iterator"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
@ -173,6 +179,29 @@ version = "0.1.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
|
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ffizz-header"
|
||||||
|
version = "0.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6a6b3ae8dccc2b5edfc7805a0c26cc776ae521fd5f6fdd693520e130abcdce06"
|
||||||
|
dependencies = [
|
||||||
|
"ffizz-macros",
|
||||||
|
"itertools",
|
||||||
|
"linkme",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ffizz-macros"
|
||||||
|
version = "0.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "56603703fdb7bcae099f7212b9afb83f0d057236e42d87c894ba6b34ad77ac18"
|
||||||
|
dependencies = [
|
||||||
|
"itertools",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flate2"
|
name = "flate2"
|
||||||
version = "1.0.22"
|
version = "1.0.22"
|
||||||
|
@ -265,6 +294,15 @@ dependencies = [
|
||||||
"unicode-normalization",
|
"unicode-normalization",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itertools"
|
||||||
|
version = "0.10.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
@ -312,6 +350,26 @@ dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linkme"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "22bcb06ef182e7557cf18d85bd151319d657bd8f699d381435781871f3027af8"
|
||||||
|
dependencies = [
|
||||||
|
"linkme-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linkme-impl"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "83f2011c1121c45eb4d9639cf5dcbae9622d2978fc5e922a346bfdc6c46700b5"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.17"
|
version = "0.4.17"
|
||||||
|
@ -376,18 +434,18 @@ checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.36"
|
version = "1.0.50"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
|
checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.17"
|
version = "1.0.23"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "632d02bff7f874a36f33ea8bb416cd484b90cc66c1194b1a1110d067a7013f58"
|
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
@ -525,13 +583,13 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.91"
|
version = "1.0.107"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d"
|
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"unicode-xid",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -559,6 +617,7 @@ name = "taskchampion-lib"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"ffizz-header",
|
||||||
"libc",
|
"libc",
|
||||||
"taskchampion",
|
"taskchampion",
|
||||||
]
|
]
|
||||||
|
@ -630,6 +689,12 @@ version = "0.3.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f"
|
checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-normalization"
|
name = "unicode-normalization"
|
||||||
version = "0.1.19"
|
version = "0.1.19"
|
||||||
|
@ -645,12 +710,6 @@ version = "0.1.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-xid"
|
|
||||||
version = "0.2.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "untrusted"
|
name = "untrusted"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
|
|
|
@ -13,9 +13,11 @@ fn build_bindings_tests(suites: &[&'static str]) {
|
||||||
"UNITY_OUTPUT_CHAR_HEADER_DECLARATION",
|
"UNITY_OUTPUT_CHAR_HEADER_DECLARATION",
|
||||||
"test_output(char c)",
|
"test_output(char c)",
|
||||||
);
|
);
|
||||||
build.file("src/bindings_tests/unity/unity.c");
|
|
||||||
|
|
||||||
let mut files = vec!["src/bindings_tests/test.c".to_string()];
|
let mut files = vec![
|
||||||
|
"src/bindings_tests/test.c".into(),
|
||||||
|
"src/bindings_tests/unity/unity.c".into(),
|
||||||
|
];
|
||||||
for suite in suites {
|
for suite in suites {
|
||||||
files.push(format!("src/bindings_tests/{}.c", suite));
|
files.push(format!("src/bindings_tests/{}.c", suite));
|
||||||
}
|
}
|
||||||
|
@ -23,6 +25,7 @@ fn build_bindings_tests(suites: &[&'static str]) {
|
||||||
build.file(&file);
|
build.file(&file);
|
||||||
println!("cargo:rerun-if-changed={}", file);
|
println!("cargo:rerun-if-changed={}", file);
|
||||||
}
|
}
|
||||||
|
println!("cargo:rerun-if-changed=../lib/taskchampion.h");
|
||||||
|
|
||||||
build.compile("bindings-tests");
|
build.compile("bindings-tests");
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ edition = "2018"
|
||||||
libc = "0.2.136"
|
libc = "0.2.136"
|
||||||
taskchampion = { path = "../taskchampion" }
|
taskchampion = { path = "../taskchampion" }
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
|
ffizz-header = "0.3"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
pretty_assertions = "1"
|
pretty_assertions = "1"
|
||||||
|
|
|
@ -1,76 +0,0 @@
|
||||||
/**
|
|
||||||
* TaskChampion
|
|
||||||
*
|
|
||||||
* This file defines the C interface to libtaskchampion. This is a thin
|
|
||||||
* wrapper around the Rust `taskchampion` crate. Refer to the documentation
|
|
||||||
* for that crate at https://docs.rs/taskchampion/latest/taskchampion/ for API
|
|
||||||
* details. The comments in this file focus mostly on the low-level details of
|
|
||||||
* passing values to and from TaskChampion.
|
|
||||||
*
|
|
||||||
* # Overview
|
|
||||||
*
|
|
||||||
* This library defines two major types used to interact with the API, that map directly
|
|
||||||
* to Rust types.
|
|
||||||
*
|
|
||||||
* * TCReplica - see https://docs.rs/taskchampion/latest/taskchampion/struct.Replica.html
|
|
||||||
* * TCTask - see https://docs.rs/taskchampion/latest/taskchampion/struct.Task.html
|
|
||||||
* * TCServer - see https://docs.rs/taskchampion/latest/taskchampion/trait.Server.html
|
|
||||||
* * TCWorkingSet - see https://docs.rs/taskchampion/latest/taskchampion/struct.WorkingSet.html
|
|
||||||
*
|
|
||||||
* It also defines a few utility types:
|
|
||||||
*
|
|
||||||
* * TCString - a wrapper around both C (NUL-terminated) and Rust (always utf-8) strings.
|
|
||||||
* * TC…List - a list of objects represented as a C array
|
|
||||||
* * see below for the remainder
|
|
||||||
*
|
|
||||||
* # Safety
|
|
||||||
*
|
|
||||||
* Each type contains specific instructions to ensure memory safety.
|
|
||||||
* The general rules are as follows.
|
|
||||||
*
|
|
||||||
* No types in this library are threadsafe. All values should be used in only
|
|
||||||
* one thread for their entire lifetime. It is safe to use unrelated values in
|
|
||||||
* different threads (for example, different threads may use different
|
|
||||||
* TCReplica values concurrently).
|
|
||||||
*
|
|
||||||
* ## Pass by Pointer
|
|
||||||
*
|
|
||||||
* Several types such as TCReplica and TCString are "opaque" types and always
|
|
||||||
* handled as pointers in C. The bytes these pointers address are private to
|
|
||||||
* the Rust implemetation and must not be accessed from C.
|
|
||||||
*
|
|
||||||
* Pass-by-pointer values have exactly one owner, and that owner is responsible
|
|
||||||
* for freeing the value (using a `tc_…_free` function), or transferring
|
|
||||||
* ownership elsewhere. Except where documented otherwise, when a value is
|
|
||||||
* passed to C, ownership passes to C as well. When a value is passed to Rust,
|
|
||||||
* ownership stays with the C code. The exception is TCString, ownership of
|
|
||||||
* which passes to Rust when it is used as a function argument.
|
|
||||||
*
|
|
||||||
* The limited circumstances where one value must not outlive another, due to
|
|
||||||
* pointer references between them, are documented below.
|
|
||||||
*
|
|
||||||
* ## Pass by Value
|
|
||||||
*
|
|
||||||
* Types such as TCUuid and TC…List are passed by value, and contain fields
|
|
||||||
* that are accessible from C. C code is free to access the content of these
|
|
||||||
* types in a _read_only_ fashion.
|
|
||||||
*
|
|
||||||
* Pass-by-value values that contain pointers also have exactly one owner,
|
|
||||||
* responsible for freeing the value or transferring ownership. The tc_…_free
|
|
||||||
* functions for these types will replace the pointers with NULL to guard
|
|
||||||
* against use-after-free errors. The interior pointers in such values should
|
|
||||||
* never be freed directly (for example, `tc_string_free(tcuda.value)` is an
|
|
||||||
* error).
|
|
||||||
*
|
|
||||||
* TCUuid is a special case, because it does not contain pointers. It can be
|
|
||||||
* freely copied and need not be freed.
|
|
||||||
*
|
|
||||||
* ## Lists
|
|
||||||
*
|
|
||||||
* Lists are a special kind of pass-by-value type. Each contains `len` and
|
|
||||||
* `items`, where `items` is an array of length `len`. Lists, and the values
|
|
||||||
* in the `items` array, must be treated as read-only. On return from an API
|
|
||||||
* function, a list's ownership is with the C caller, which must eventually
|
|
||||||
* free the list. List data must be freed with the `tc_…_list_free` function.
|
|
||||||
* It is an error to free any value in the `items` array of a list.
|
|
||||||
*/
|
|
|
@ -2,6 +2,10 @@ use crate::traits::*;
|
||||||
use crate::types::*;
|
use crate::types::*;
|
||||||
use taskchampion::chrono::prelude::*;
|
use taskchampion::chrono::prelude::*;
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 400)]
|
||||||
|
/// ***** TCAnnotation *****
|
||||||
|
///
|
||||||
/// TCAnnotation contains the details of an annotation.
|
/// TCAnnotation contains the details of an annotation.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
|
@ -17,6 +21,15 @@ use taskchampion::chrono::prelude::*;
|
||||||
/// after the call returns. In fact, the value will be zeroed out to ensure this.
|
/// after the call returns. In fact, the value will be zeroed out to ensure this.
|
||||||
///
|
///
|
||||||
/// TCAnnotations are not threadsafe.
|
/// TCAnnotations are not threadsafe.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// typedef struct TCAnnotation {
|
||||||
|
/// // Time the annotation was made. Must be nonzero.
|
||||||
|
/// time_t entry;
|
||||||
|
/// // Content of the annotation. Must not be NULL.
|
||||||
|
/// TCString description;
|
||||||
|
/// } TCAnnotation;
|
||||||
|
/// ```
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct TCAnnotation {
|
pub struct TCAnnotation {
|
||||||
/// Time the annotation was made. Must be nonzero.
|
/// Time the annotation was made. Must be nonzero.
|
||||||
|
@ -62,18 +75,34 @@ impl Default for TCAnnotation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 410)]
|
||||||
|
/// ***** TCAnnotationList *****
|
||||||
|
///
|
||||||
/// TCAnnotationList represents a list of annotations.
|
/// TCAnnotationList represents a list of annotations.
|
||||||
///
|
///
|
||||||
/// The content of this struct must be treated as read-only.
|
/// The content of this struct must be treated as read-only.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// typedef struct TCAnnotationList {
|
||||||
|
/// // number of annotations in items
|
||||||
|
/// size_t len;
|
||||||
|
/// // reserved
|
||||||
|
/// size_t _u1;
|
||||||
|
/// // Array of annotations. These remain owned by the TCAnnotationList instance and will be freed by
|
||||||
|
/// // tc_annotation_list_free. This pointer is never NULL for a valid TCAnnotationList.
|
||||||
|
/// struct TCAnnotation *items;
|
||||||
|
/// } TCAnnotationList;
|
||||||
|
/// ```
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct TCAnnotationList {
|
pub struct TCAnnotationList {
|
||||||
/// number of annotations in items
|
/// number of annotations in items
|
||||||
len: libc::size_t,
|
len: libc::size_t,
|
||||||
|
|
||||||
/// total size of items (internal use only)
|
/// total size of items (internal use only)
|
||||||
_capacity: libc::size_t,
|
capacity: libc::size_t,
|
||||||
|
|
||||||
/// array of annotations. these remain owned by the TCAnnotationList instance and will be freed by
|
/// Array of annotations. These remain owned by the TCAnnotationList instance and will be freed by
|
||||||
/// tc_annotation_list_free. This pointer is never NULL for a valid TCAnnotationList.
|
/// tc_annotation_list_free. This pointer is never NULL for a valid TCAnnotationList.
|
||||||
items: *mut TCAnnotation,
|
items: *mut TCAnnotation,
|
||||||
}
|
}
|
||||||
|
@ -84,7 +113,7 @@ impl CList for TCAnnotationList {
|
||||||
unsafe fn from_raw_parts(items: *mut Self::Element, len: usize, cap: usize) -> Self {
|
unsafe fn from_raw_parts(items: *mut Self::Element, len: usize, cap: usize) -> Self {
|
||||||
TCAnnotationList {
|
TCAnnotationList {
|
||||||
len,
|
len,
|
||||||
_capacity: cap,
|
capacity: cap,
|
||||||
items,
|
items,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,12 +128,18 @@ impl CList for TCAnnotationList {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn into_raw_parts(self) -> (*mut Self::Element, usize, usize) {
|
fn into_raw_parts(self) -> (*mut Self::Element, usize, usize) {
|
||||||
(self.items, self.len, self._capacity)
|
(self.items, self.len, self.capacity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 401)]
|
||||||
/// Free a TCAnnotation instance. The instance, and the TCString it contains, must not be used
|
/// Free a TCAnnotation instance. The instance, and the TCString it contains, must not be used
|
||||||
/// after this call.
|
/// after this call.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C void tc_annotation_free(struct TCAnnotation *tcann);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_annotation_free(tcann: *mut TCAnnotation) {
|
pub unsafe extern "C" fn tc_annotation_free(tcann: *mut TCAnnotation) {
|
||||||
debug_assert!(!tcann.is_null());
|
debug_assert!(!tcann.is_null());
|
||||||
|
@ -115,10 +150,16 @@ pub unsafe extern "C" fn tc_annotation_free(tcann: *mut TCAnnotation) {
|
||||||
drop(annotation);
|
drop(annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 411)]
|
||||||
/// Free a TCAnnotationList instance. The instance, and all TCAnnotations it contains, must not be used after
|
/// Free a TCAnnotationList instance. The instance, and all TCAnnotations it contains, must not be used after
|
||||||
/// this call.
|
/// this call.
|
||||||
///
|
///
|
||||||
/// When this call returns, the `items` pointer will be NULL, signalling an invalid TCAnnotationList.
|
/// When this call returns, the `items` pointer will be NULL, signalling an invalid TCAnnotationList.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C void tc_annotation_list_free(struct TCAnnotationList *tcanns);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_annotation_list_free(tcanns: *mut TCAnnotationList) {
|
pub unsafe extern "C" fn tc_annotation_list_free(tcanns: *mut TCAnnotationList) {
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
|
@ -137,7 +178,7 @@ mod test {
|
||||||
let tcanns = unsafe { TCAnnotationList::return_val(Vec::new()) };
|
let tcanns = unsafe { TCAnnotationList::return_val(Vec::new()) };
|
||||||
assert!(!tcanns.items.is_null());
|
assert!(!tcanns.items.is_null());
|
||||||
assert_eq!(tcanns.len, 0);
|
assert_eq!(tcanns.len, 0);
|
||||||
assert_eq!(tcanns._capacity, 0);
|
assert_eq!(tcanns.capacity, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -147,6 +188,6 @@ mod test {
|
||||||
unsafe { tc_annotation_list_free(&mut tcanns) };
|
unsafe { tc_annotation_list_free(&mut tcanns) };
|
||||||
assert!(tcanns.items.is_null());
|
assert!(tcanns.items.is_null());
|
||||||
assert_eq!(tcanns.len, 0);
|
assert_eq!(tcanns.len, 0);
|
||||||
assert_eq!(tcanns._capacity, 0);
|
assert_eq!(tcanns.capacity, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,21 @@
|
||||||
use crate::traits::*;
|
use crate::traits::*;
|
||||||
use crate::types::*;
|
use crate::types::*;
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 600)]
|
||||||
|
/// ***** TCKV *****
|
||||||
|
///
|
||||||
/// TCKV contains a key/value pair that is part of a task.
|
/// TCKV contains a key/value pair that is part of a task.
|
||||||
///
|
///
|
||||||
/// Neither key nor value are ever NULL. They remain owned by the TCKV and
|
/// Neither key nor value are ever NULL. They remain owned by the TCKV and
|
||||||
/// will be freed when it is freed with tc_kv_list_free.
|
/// will be freed when it is freed with tc_kv_list_free.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// typedef struct TCKV {
|
||||||
|
/// struct TCString key;
|
||||||
|
/// struct TCString value;
|
||||||
|
/// } TCKV;
|
||||||
|
/// ```
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct TCKV {
|
pub struct TCKV {
|
||||||
pub key: TCString,
|
pub key: TCString,
|
||||||
|
@ -37,9 +48,25 @@ impl PassByValue for TCKV {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 610)]
|
||||||
|
/// ***** TCKVList *****
|
||||||
|
///
|
||||||
/// TCKVList represents a list of key/value pairs.
|
/// TCKVList represents a list of key/value pairs.
|
||||||
///
|
///
|
||||||
/// The content of this struct must be treated as read-only.
|
/// The content of this struct must be treated as read-only.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// typedef struct TCKVList {
|
||||||
|
/// // number of key/value pairs in items
|
||||||
|
/// size_t len;
|
||||||
|
/// // reserved
|
||||||
|
/// size_t _u1;
|
||||||
|
/// // Array of TCKV's. These remain owned by the TCKVList instance and will be freed by
|
||||||
|
/// // tc_kv_list_free. This pointer is never NULL for a valid TCKVList.
|
||||||
|
/// struct TCKV *items;
|
||||||
|
/// } TCKVList;
|
||||||
|
/// ```
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct TCKVList {
|
pub struct TCKVList {
|
||||||
/// number of key/value pairs in items
|
/// number of key/value pairs in items
|
||||||
|
@ -48,7 +75,7 @@ pub struct TCKVList {
|
||||||
/// total size of items (internal use only)
|
/// total size of items (internal use only)
|
||||||
_capacity: libc::size_t,
|
_capacity: libc::size_t,
|
||||||
|
|
||||||
/// array of TCKV's. these remain owned by the TCKVList instance and will be freed by
|
/// Array of TCKV's. These remain owned by the TCKVList instance and will be freed by
|
||||||
/// tc_kv_list_free. This pointer is never NULL for a valid TCKVList.
|
/// tc_kv_list_free. This pointer is never NULL for a valid TCKVList.
|
||||||
items: *mut TCKV,
|
items: *mut TCKV,
|
||||||
}
|
}
|
||||||
|
@ -78,10 +105,18 @@ impl CList for TCKVList {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: callers never have a TCKV that is not in a list, so there is no tc_kv_free.
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 611)]
|
||||||
/// Free a TCKVList instance. The instance, and all TCKVs it contains, must not be used after
|
/// Free a TCKVList instance. The instance, and all TCKVs it contains, must not be used after
|
||||||
/// this call.
|
/// this call.
|
||||||
///
|
///
|
||||||
/// When this call returns, the `items` pointer will be NULL, signalling an invalid TCKVList.
|
/// When this call returns, the `items` pointer will be NULL, signalling an invalid TCKVList.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C void tc_kv_list_free(struct TCKVList *tckvs);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_kv_list_free(tckvs: *mut TCKVList) {
|
pub unsafe extern "C" fn tc_kv_list_free(tckvs: *mut TCKVList) {
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
|
|
|
@ -12,6 +12,117 @@
|
||||||
#![deny(clippy::extra_unused_lifetimes)]
|
#![deny(clippy::extra_unused_lifetimes)]
|
||||||
#![deny(clippy::unnecessary_to_owned)]
|
#![deny(clippy::unnecessary_to_owned)]
|
||||||
|
|
||||||
|
// ffizz_header orders:
|
||||||
|
//
|
||||||
|
// 000-099: header matter
|
||||||
|
// 100-199: TCResult
|
||||||
|
// 200-299: TCString / List
|
||||||
|
// 300-399: TCUuid / List
|
||||||
|
// 400-499: TCAnnotation / List
|
||||||
|
// 500-599: TCUda / List
|
||||||
|
// 600-699: TCKV / List
|
||||||
|
// 700-799: TCStatus
|
||||||
|
// 800-899: TCServer
|
||||||
|
// 900-999: TCReplica
|
||||||
|
// 1000-1099: TCTask / List
|
||||||
|
// 1100-1199: TCWorkingSet
|
||||||
|
// 10000-10099: footer
|
||||||
|
|
||||||
|
ffizz_header::snippet! {
|
||||||
|
#[ffizz(name="intro", order=0)]
|
||||||
|
/// TaskChampion
|
||||||
|
///
|
||||||
|
/// This file defines the C interface to libtaskchampion. This is a thin wrapper around the Rust
|
||||||
|
/// `taskchampion` crate. Refer to the documentation for that crate at
|
||||||
|
/// https://docs.rs/taskchampion/latest/taskchampion/ for API details. The comments in this file
|
||||||
|
/// focus mostly on the low-level details of passing values to and from TaskChampion.
|
||||||
|
///
|
||||||
|
/// # Overview
|
||||||
|
///
|
||||||
|
/// This library defines two major types used to interact with the API, that map directly to Rust
|
||||||
|
/// types.
|
||||||
|
///
|
||||||
|
/// * TCReplica - see https://docs.rs/taskchampion/latest/taskchampion/struct.Replica.html * TCTask
|
||||||
|
/// - see https://docs.rs/taskchampion/latest/taskchampion/struct.Task.html * TCServer - see
|
||||||
|
/// https://docs.rs/taskchampion/latest/taskchampion/trait.Server.html * TCWorkingSet - see
|
||||||
|
/// https://docs.rs/taskchampion/latest/taskchampion/struct.WorkingSet.html
|
||||||
|
///
|
||||||
|
/// It also defines a few utility types:
|
||||||
|
///
|
||||||
|
/// * TCString - a wrapper around both C (NUL-terminated) and Rust (always utf-8) strings. *
|
||||||
|
/// TC…List - a list of objects represented as a C array * see below for the remainder
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// Each type contains specific instructions to ensure memory safety. The general rules are as
|
||||||
|
/// follows.
|
||||||
|
///
|
||||||
|
/// No types in this library are threadsafe. All values should be used in only one thread for their
|
||||||
|
/// entire lifetime. It is safe to use unrelated values in different threads (for example,
|
||||||
|
/// different threads may use different TCReplica values concurrently).
|
||||||
|
///
|
||||||
|
/// ## Pass by Pointer
|
||||||
|
///
|
||||||
|
/// Several types such as TCReplica and TCString are "opaque" types and always handled as pointers
|
||||||
|
/// in C. The bytes these pointers address are private to the Rust implemetation and must not be
|
||||||
|
/// accessed from C.
|
||||||
|
///
|
||||||
|
/// Pass-by-pointer values have exactly one owner, and that owner is responsible for freeing the
|
||||||
|
/// value (using a `tc_…_free` function), or transferring ownership elsewhere. Except where
|
||||||
|
/// documented otherwise, when a value is passed to C, ownership passes to C as well. When a value
|
||||||
|
/// is passed to Rust, ownership stays with the C code. The exception is TCString, ownership of
|
||||||
|
/// which passes to Rust when it is used as a function argument.
|
||||||
|
///
|
||||||
|
/// The limited circumstances where one value must not outlive another, due to pointer references
|
||||||
|
/// between them, are documented below.
|
||||||
|
///
|
||||||
|
/// ## Pass by Value
|
||||||
|
///
|
||||||
|
/// Types such as TCUuid and TC…List are passed by value, and contain fields that are accessible
|
||||||
|
/// from C. C code is free to access the content of these types in a _read_only_ fashion.
|
||||||
|
///
|
||||||
|
/// Pass-by-value values that contain pointers also have exactly one owner, responsible for freeing
|
||||||
|
/// the value or transferring ownership. The tc_…_free functions for these types will replace the
|
||||||
|
/// pointers with NULL to guard against use-after-free errors. The interior pointers in such values
|
||||||
|
/// should never be freed directly (for example, `tc_string_free(tcuda.value)` is an error).
|
||||||
|
///
|
||||||
|
/// TCUuid is a special case, because it does not contain pointers. It can be freely copied and
|
||||||
|
/// need not be freed.
|
||||||
|
///
|
||||||
|
/// ## Lists
|
||||||
|
///
|
||||||
|
/// Lists are a special kind of pass-by-value type. Each contains `len` and `items`, where `items`
|
||||||
|
/// is an array of length `len`. Lists, and the values in the `items` array, must be treated as
|
||||||
|
/// read-only. On return from an API function, a list's ownership is with the C caller, which must
|
||||||
|
/// eventually free the list. List data must be freed with the `tc_…_list_free` function. It is an
|
||||||
|
/// error to free any value in the `items` array of a list.
|
||||||
|
}
|
||||||
|
|
||||||
|
ffizz_header::snippet! {
|
||||||
|
#[ffizz(name="topmatter", order=1)]
|
||||||
|
/// ```c
|
||||||
|
/// #ifndef TASKCHAMPION_H
|
||||||
|
/// #define TASKCHAMPION_H
|
||||||
|
///
|
||||||
|
/// #include <stdbool.h>
|
||||||
|
/// #include <stdint.h>
|
||||||
|
/// #include <time.h>
|
||||||
|
///
|
||||||
|
/// #ifdef __cplusplus
|
||||||
|
/// #define EXTERN_C extern "C"
|
||||||
|
/// #else
|
||||||
|
/// #define EXTERN_C
|
||||||
|
/// #endif // __cplusplus
|
||||||
|
/// ```
|
||||||
|
}
|
||||||
|
|
||||||
|
ffizz_header::snippet! {
|
||||||
|
#[ffizz(name="bottomatter", order=10000)]
|
||||||
|
/// ```c
|
||||||
|
/// #endif /* TASKCHAMPION_H */
|
||||||
|
/// ```
|
||||||
|
}
|
||||||
|
|
||||||
mod traits;
|
mod traits;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
|
@ -53,3 +164,9 @@ pub(crate) mod types {
|
||||||
pub(crate) use crate::uuid::{TCUuid, TCUuidList};
|
pub(crate) use crate::uuid::{TCUuid, TCUuidList};
|
||||||
pub(crate) use crate::workingset::TCWorkingSet;
|
pub(crate) use crate::workingset::TCWorkingSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
/// Generate the taskchapion.h header
|
||||||
|
pub fn generate_header() -> String {
|
||||||
|
ffizz_header::generate()
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,10 @@ use crate::util::err_to_ruststring;
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
use taskchampion::{Replica, StorageConfig};
|
use taskchampion::{Replica, StorageConfig};
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 900)]
|
||||||
|
/// ***** TCReplica *****
|
||||||
|
///
|
||||||
/// A replica represents an instance of a user's task data, providing an easy interface
|
/// A replica represents an instance of a user's task data, providing an easy interface
|
||||||
/// for querying and modifying that data.
|
/// for querying and modifying that data.
|
||||||
///
|
///
|
||||||
|
@ -26,6 +30,10 @@ use taskchampion::{Replica, StorageConfig};
|
||||||
/// Once passed to `tc_replica_free`, a `*TCReplica` becomes invalid and must not be used again.
|
/// Once passed to `tc_replica_free`, a `*TCReplica` becomes invalid and must not be used again.
|
||||||
///
|
///
|
||||||
/// TCReplicas are not threadsafe.
|
/// TCReplicas are not threadsafe.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// typedef struct TCReplica TCReplica;
|
||||||
|
/// ```
|
||||||
pub struct TCReplica {
|
pub struct TCReplica {
|
||||||
/// The wrapped Replica
|
/// The wrapped Replica
|
||||||
inner: Replica,
|
inner: Replica,
|
||||||
|
@ -122,8 +130,14 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 901)]
|
||||||
/// Create a new TCReplica with an in-memory database. The contents of the database will be
|
/// Create a new TCReplica with an in-memory database. The contents of the database will be
|
||||||
/// lost when it is freed with tc_replica_free.
|
/// lost when it is freed with tc_replica_free.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C struct TCReplica *tc_replica_new_in_memory(void);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_replica_new_in_memory() -> *mut TCReplica {
|
pub unsafe extern "C" fn tc_replica_new_in_memory() -> *mut TCReplica {
|
||||||
let storage = StorageConfig::InMemory
|
let storage = StorageConfig::InMemory
|
||||||
|
@ -134,9 +148,17 @@ pub unsafe extern "C" fn tc_replica_new_in_memory() -> *mut TCReplica {
|
||||||
unsafe { TCReplica::from(Replica::new(storage)).return_ptr() }
|
unsafe { TCReplica::from(Replica::new(storage)).return_ptr() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 901)]
|
||||||
/// Create a new TCReplica with an on-disk database having the given filename. On error, a string
|
/// Create a new TCReplica with an on-disk database having the given filename. On error, a string
|
||||||
/// is written to the error_out parameter (if it is not NULL) and NULL is returned. The caller
|
/// is written to the error_out parameter (if it is not NULL) and NULL is returned. The caller
|
||||||
/// must free this string.
|
/// must free this string.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C struct TCReplica *tc_replica_new_on_disk(struct TCString path,
|
||||||
|
/// bool create_if_missing,
|
||||||
|
/// struct TCString *error_out);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_replica_new_on_disk(
|
pub unsafe extern "C" fn tc_replica_new_on_disk(
|
||||||
path: TCString,
|
path: TCString,
|
||||||
|
@ -164,9 +186,15 @@ pub unsafe extern "C" fn tc_replica_new_on_disk(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 902)]
|
||||||
/// Get a list of all tasks in the replica.
|
/// Get a list of all tasks in the replica.
|
||||||
///
|
///
|
||||||
/// Returns a TCTaskList with a NULL items field on error.
|
/// Returns a TCTaskList with a NULL items field on error.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C struct TCTaskList tc_replica_all_tasks(struct TCReplica *rep);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_replica_all_tasks(rep: *mut TCReplica) -> TCTaskList {
|
pub unsafe extern "C" fn tc_replica_all_tasks(rep: *mut TCReplica) -> TCTaskList {
|
||||||
wrap(
|
wrap(
|
||||||
|
@ -197,11 +225,17 @@ pub unsafe extern "C" fn tc_replica_all_tasks(rep: *mut TCReplica) -> TCTaskList
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 902)]
|
||||||
/// Get a list of all uuids for tasks in the replica.
|
/// Get a list of all uuids for tasks in the replica.
|
||||||
///
|
///
|
||||||
/// Returns a TCUuidList with a NULL items field on error.
|
/// Returns a TCUuidList with a NULL items field on error.
|
||||||
///
|
///
|
||||||
/// The caller must free the UUID list with `tc_uuid_list_free`.
|
/// The caller must free the UUID list with `tc_uuid_list_free`.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C struct TCUuidList tc_replica_all_task_uuids(struct TCReplica *rep);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_replica_all_task_uuids(rep: *mut TCReplica) -> TCUuidList {
|
pub unsafe extern "C" fn tc_replica_all_task_uuids(rep: *mut TCReplica) -> TCUuidList {
|
||||||
wrap(
|
wrap(
|
||||||
|
@ -222,10 +256,16 @@ pub unsafe extern "C" fn tc_replica_all_task_uuids(rep: *mut TCReplica) -> TCUui
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 902)]
|
||||||
/// Get the current working set for this replica. The resulting value must be freed
|
/// Get the current working set for this replica. The resulting value must be freed
|
||||||
/// with tc_working_set_free.
|
/// with tc_working_set_free.
|
||||||
///
|
///
|
||||||
/// Returns NULL on error.
|
/// Returns NULL on error.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C struct TCWorkingSet *tc_replica_working_set(struct TCReplica *rep);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_replica_working_set(rep: *mut TCReplica) -> *mut TCWorkingSet {
|
pub unsafe extern "C" fn tc_replica_working_set(rep: *mut TCReplica) -> *mut TCWorkingSet {
|
||||||
wrap(
|
wrap(
|
||||||
|
@ -240,10 +280,16 @@ pub unsafe extern "C" fn tc_replica_working_set(rep: *mut TCReplica) -> *mut TCW
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 902)]
|
||||||
/// Get an existing task by its UUID.
|
/// Get an existing task by its UUID.
|
||||||
///
|
///
|
||||||
/// Returns NULL when the task does not exist, and on error. Consult tc_replica_error
|
/// Returns NULL when the task does not exist, and on error. Consult tc_replica_error
|
||||||
/// to distinguish the two conditions.
|
/// to distinguish the two conditions.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C struct TCTask *tc_replica_get_task(struct TCReplica *rep, struct TCUuid tcuuid);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_replica_get_task(rep: *mut TCReplica, tcuuid: TCUuid) -> *mut TCTask {
|
pub unsafe extern "C" fn tc_replica_get_task(rep: *mut TCReplica, tcuuid: TCUuid) -> *mut TCTask {
|
||||||
wrap(
|
wrap(
|
||||||
|
@ -265,9 +311,17 @@ pub unsafe extern "C" fn tc_replica_get_task(rep: *mut TCReplica, tcuuid: TCUuid
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 902)]
|
||||||
/// Create a new task. The task must not already exist.
|
/// Create a new task. The task must not already exist.
|
||||||
///
|
///
|
||||||
/// Returns the task, or NULL on error.
|
/// Returns the task, or NULL on error.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C struct TCTask *tc_replica_new_task(struct TCReplica *rep,
|
||||||
|
/// enum TCStatus status,
|
||||||
|
/// struct TCString description);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_replica_new_task(
|
pub unsafe extern "C" fn tc_replica_new_task(
|
||||||
rep: *mut TCReplica,
|
rep: *mut TCReplica,
|
||||||
|
@ -290,9 +344,15 @@ pub unsafe extern "C" fn tc_replica_new_task(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 902)]
|
||||||
/// Create a new task. The task must not already exist.
|
/// Create a new task. The task must not already exist.
|
||||||
///
|
///
|
||||||
/// Returns the task, or NULL on error.
|
/// Returns the task, or NULL on error.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C struct TCTask *tc_replica_import_task_with_uuid(struct TCReplica *rep, struct TCUuid tcuuid);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_replica_import_task_with_uuid(
|
pub unsafe extern "C" fn tc_replica_import_task_with_uuid(
|
||||||
rep: *mut TCReplica,
|
rep: *mut TCReplica,
|
||||||
|
@ -314,9 +374,15 @@ pub unsafe extern "C" fn tc_replica_import_task_with_uuid(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 902)]
|
||||||
/// Synchronize this replica with a server.
|
/// Synchronize this replica with a server.
|
||||||
///
|
///
|
||||||
/// The `server` argument remains owned by the caller, and must be freed explicitly.
|
/// The `server` argument remains owned by the caller, and must be freed explicitly.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C TCResult tc_replica_sync(struct TCReplica *rep, struct TCServer *server, bool avoid_snapshots);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_replica_sync(
|
pub unsafe extern "C" fn tc_replica_sync(
|
||||||
rep: *mut TCReplica,
|
rep: *mut TCReplica,
|
||||||
|
@ -340,10 +406,16 @@ pub unsafe extern "C" fn tc_replica_sync(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 902)]
|
||||||
/// Undo local operations until the most recent UndoPoint.
|
/// Undo local operations until the most recent UndoPoint.
|
||||||
///
|
///
|
||||||
/// If undone_out is not NULL, then on success it is set to 1 if operations were undone, or 0 if
|
/// If undone_out is not NULL, then on success it is set to 1 if operations were undone, or 0 if
|
||||||
/// there are no operations that can be done.
|
/// there are no operations that can be done.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C TCResult tc_replica_undo(struct TCReplica *rep, int32_t *undone_out);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_replica_undo(rep: *mut TCReplica, undone_out: *mut i32) -> TCResult {
|
pub unsafe extern "C" fn tc_replica_undo(rep: *mut TCReplica, undone_out: *mut i32) -> TCResult {
|
||||||
wrap(
|
wrap(
|
||||||
|
@ -362,8 +434,14 @@ pub unsafe extern "C" fn tc_replica_undo(rep: *mut TCReplica, undone_out: *mut i
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 902)]
|
||||||
/// Get the number of local, un-synchronized operations (not including undo points), or -1 on
|
/// Get the number of local, un-synchronized operations (not including undo points), or -1 on
|
||||||
/// error.
|
/// error.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C int64_t tc_replica_num_local_operations(struct TCReplica *rep);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_replica_num_local_operations(rep: *mut TCReplica) -> i64 {
|
pub unsafe extern "C" fn tc_replica_num_local_operations(rep: *mut TCReplica) -> i64 {
|
||||||
wrap(
|
wrap(
|
||||||
|
@ -376,7 +454,13 @@ pub unsafe extern "C" fn tc_replica_num_local_operations(rep: *mut TCReplica) ->
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 902)]
|
||||||
/// Get the number of undo points (number of undo calls possible), or -1 on error.
|
/// Get the number of undo points (number of undo calls possible), or -1 on error.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C int64_t tc_replica_num_undo_points(struct TCReplica *rep);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_replica_num_undo_points(rep: *mut TCReplica) -> i64 {
|
pub unsafe extern "C" fn tc_replica_num_undo_points(rep: *mut TCReplica) -> i64 {
|
||||||
wrap(
|
wrap(
|
||||||
|
@ -389,10 +473,16 @@ pub unsafe extern "C" fn tc_replica_num_undo_points(rep: *mut TCReplica) -> i64
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 902)]
|
||||||
/// Add an UndoPoint, if one has not already been added by this Replica. This occurs automatically
|
/// Add an UndoPoint, if one has not already been added by this Replica. This occurs automatically
|
||||||
/// when a change is made. The `force` flag allows forcing a new UndoPoint even if one has already
|
/// when a change is made. The `force` flag allows forcing a new UndoPoint even if one has already
|
||||||
/// been created by this Replica, and may be useful when a Replica instance is held for a long time
|
/// been created by this Replica, and may be useful when a Replica instance is held for a long time
|
||||||
/// and used to apply more than one user-visible change.
|
/// and used to apply more than one user-visible change.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C TCResult tc_replica_add_undo_point(struct TCReplica *rep, bool force);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_replica_add_undo_point(rep: *mut TCReplica, force: bool) -> TCResult {
|
pub unsafe extern "C" fn tc_replica_add_undo_point(rep: *mut TCReplica, force: bool) -> TCResult {
|
||||||
wrap(
|
wrap(
|
||||||
|
@ -405,9 +495,15 @@ pub unsafe extern "C" fn tc_replica_add_undo_point(rep: *mut TCReplica, force: b
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 902)]
|
||||||
/// Rebuild this replica's working set, based on whether tasks are pending or not. If `renumber`
|
/// Rebuild this replica's working set, based on whether tasks are pending or not. If `renumber`
|
||||||
/// is true, then existing tasks may be moved to new working-set indices; in any case, on
|
/// is true, then existing tasks may be moved to new working-set indices; in any case, on
|
||||||
/// completion all pending tasks are in the working set and all non- pending tasks are not.
|
/// completion all pending tasks are in the working set and all non- pending tasks are not.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C TCResult tc_replica_rebuild_working_set(struct TCReplica *rep, bool renumber);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_replica_rebuild_working_set(
|
pub unsafe extern "C" fn tc_replica_rebuild_working_set(
|
||||||
rep: *mut TCReplica,
|
rep: *mut TCReplica,
|
||||||
|
@ -423,9 +519,15 @@ pub unsafe extern "C" fn tc_replica_rebuild_working_set(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 902)]
|
||||||
/// Get the latest error for a replica, or a string with NULL ptr if no error exists. Subsequent
|
/// Get the latest error for a replica, or a string with NULL ptr if no error exists. Subsequent
|
||||||
/// calls to this function will return NULL. The rep pointer must not be NULL. The caller must
|
/// calls to this function will return NULL. The rep pointer must not be NULL. The caller must
|
||||||
/// free the returned string.
|
/// free the returned string.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C struct TCString tc_replica_error(struct TCReplica *rep);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_replica_error(rep: *mut TCReplica) -> TCString {
|
pub unsafe extern "C" fn tc_replica_error(rep: *mut TCReplica) -> TCString {
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
|
@ -443,8 +545,14 @@ pub unsafe extern "C" fn tc_replica_error(rep: *mut TCReplica) -> TCString {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 903)]
|
||||||
/// Free a replica. The replica may not be used after this function returns and must not be freed
|
/// Free a replica. The replica may not be used after this function returns and must not be freed
|
||||||
/// more than once.
|
/// more than once.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C void tc_replica_free(struct TCReplica *rep);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_replica_free(rep: *mut TCReplica) {
|
pub unsafe extern "C" fn tc_replica_free(rep: *mut TCReplica) {
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
|
|
|
@ -1,7 +1,23 @@
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 100)]
|
||||||
|
/// ***** TCResult *****
|
||||||
|
///
|
||||||
/// A result from a TC operation. Typically if this value is TC_RESULT_ERROR,
|
/// A result from a TC operation. Typically if this value is TC_RESULT_ERROR,
|
||||||
/// the associated object's `tc_.._error` method will return an error message.
|
/// the associated object's `tc_.._error` method will return an error message.
|
||||||
/// cbindgen:prefix-with-name
|
///
|
||||||
/// cbindgen:rename-all=ScreamingSnakeCase
|
/// ```c
|
||||||
|
/// enum TCResult
|
||||||
|
/// #ifdef __cplusplus
|
||||||
|
/// : int32_t
|
||||||
|
/// #endif // __cplusplus
|
||||||
|
/// {
|
||||||
|
/// TC_RESULT_ERROR = -1,
|
||||||
|
/// TC_RESULT_OK = 0,
|
||||||
|
/// };
|
||||||
|
/// #ifndef __cplusplus
|
||||||
|
/// typedef int32_t TCResult;
|
||||||
|
/// #endif // __cplusplus
|
||||||
|
/// ```
|
||||||
#[repr(i32)]
|
#[repr(i32)]
|
||||||
pub enum TCResult {
|
pub enum TCResult {
|
||||||
Error = -1,
|
Error = -1,
|
||||||
|
|
|
@ -3,12 +3,20 @@ use crate::types::*;
|
||||||
use crate::util::err_to_ruststring;
|
use crate::util::err_to_ruststring;
|
||||||
use taskchampion::{Server, ServerConfig};
|
use taskchampion::{Server, ServerConfig};
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 800)]
|
||||||
|
/// ***** TCServer *****
|
||||||
|
///
|
||||||
/// TCServer represents an interface to a sync server. Aside from new and free, a server
|
/// TCServer represents an interface to a sync server. Aside from new and free, a server
|
||||||
/// has no C-accessible API, but is designed to be passed to `tc_replica_sync`.
|
/// has no C-accessible API, but is designed to be passed to `tc_replica_sync`.
|
||||||
///
|
///
|
||||||
/// ## Safety
|
/// ## Safety
|
||||||
///
|
///
|
||||||
/// TCServer are not threadsafe, and must not be used with multiple replicas simultaneously.
|
/// TCServer are not threadsafe, and must not be used with multiple replicas simultaneously.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// typedef struct TCServer TCServer;
|
||||||
|
/// ```
|
||||||
pub struct TCServer(Box<dyn Server>);
|
pub struct TCServer(Box<dyn Server>);
|
||||||
|
|
||||||
impl PassByPointer for TCServer {}
|
impl PassByPointer for TCServer {}
|
||||||
|
@ -53,6 +61,8 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 801)]
|
||||||
/// Create a new TCServer that operates locally (on-disk). See the TaskChampion docs for the
|
/// Create a new TCServer that operates locally (on-disk). See the TaskChampion docs for the
|
||||||
/// description of the arguments.
|
/// description of the arguments.
|
||||||
///
|
///
|
||||||
|
@ -60,6 +70,10 @@ where
|
||||||
/// returned. The caller must free this string.
|
/// returned. The caller must free this string.
|
||||||
///
|
///
|
||||||
/// The server must be freed after it is used - tc_replica_sync does not automatically free it.
|
/// The server must be freed after it is used - tc_replica_sync does not automatically free it.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C struct TCServer *tc_server_new_local(struct TCString server_dir, struct TCString *error_out);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_server_new_local(
|
pub unsafe extern "C" fn tc_server_new_local(
|
||||||
server_dir: TCString,
|
server_dir: TCString,
|
||||||
|
@ -83,6 +97,8 @@ pub unsafe extern "C" fn tc_server_new_local(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 801)]
|
||||||
/// Create a new TCServer that connects to a remote server. See the TaskChampion docs for the
|
/// Create a new TCServer that connects to a remote server. See the TaskChampion docs for the
|
||||||
/// description of the arguments.
|
/// description of the arguments.
|
||||||
///
|
///
|
||||||
|
@ -90,6 +106,13 @@ pub unsafe extern "C" fn tc_server_new_local(
|
||||||
/// returned. The caller must free this string.
|
/// returned. The caller must free this string.
|
||||||
///
|
///
|
||||||
/// The server must be freed after it is used - tc_replica_sync does not automatically free it.
|
/// The server must be freed after it is used - tc_replica_sync does not automatically free it.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C struct TCServer *tc_server_new_remote(struct TCString origin,
|
||||||
|
/// struct TCUuid client_key,
|
||||||
|
/// struct TCString encryption_secret,
|
||||||
|
/// struct TCString *error_out);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_server_new_remote(
|
pub unsafe extern "C" fn tc_server_new_remote(
|
||||||
origin: TCString,
|
origin: TCString,
|
||||||
|
@ -129,8 +152,14 @@ pub unsafe extern "C" fn tc_server_new_remote(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 802)]
|
||||||
/// Free a server. The server may not be used after this function returns and must not be freed
|
/// Free a server. The server may not be used after this function returns and must not be freed
|
||||||
/// more than once.
|
/// more than once.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C void tc_server_free(struct TCServer *server);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_server_free(server: *mut TCServer) {
|
pub unsafe extern "C" fn tc_server_free(server: *mut TCServer) {
|
||||||
debug_assert!(!server.is_null());
|
debug_assert!(!server.is_null());
|
||||||
|
|
|
@ -1,17 +1,38 @@
|
||||||
pub use taskchampion::Status;
|
pub use taskchampion::Status;
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 700)]
|
||||||
|
/// ***** TCStatus *****
|
||||||
|
///
|
||||||
/// The status of a task, as defined by the task data model.
|
/// The status of a task, as defined by the task data model.
|
||||||
/// cbindgen:prefix-with-name
|
///
|
||||||
/// cbindgen:rename-all=ScreamingSnakeCase
|
/// ```c
|
||||||
#[repr(C)]
|
/// #ifdef __cplusplus
|
||||||
|
/// typedef enum TCStatus : int32_t {
|
||||||
|
/// #else // __cplusplus
|
||||||
|
/// typedef int32_t TCStatus;
|
||||||
|
/// enum TCStatus {
|
||||||
|
/// #endif // __cplusplus
|
||||||
|
/// TC_STATUS_PENDING = 0,
|
||||||
|
/// TC_STATUS_COMPLETED = 1,
|
||||||
|
/// TC_STATUS_DELETED = 2,
|
||||||
|
/// TC_STATUS_RECURRING = 3,
|
||||||
|
/// // Unknown signifies a status in the task DB that was not
|
||||||
|
/// // recognized.
|
||||||
|
/// TC_STATUS_UNKNOWN = -1,
|
||||||
|
/// #ifdef __cplusplus
|
||||||
|
/// } TCStatus;
|
||||||
|
/// #else // __cplusplus
|
||||||
|
/// };
|
||||||
|
/// #endif // __cplusplus
|
||||||
|
/// ```
|
||||||
|
#[repr(i32)]
|
||||||
pub enum TCStatus {
|
pub enum TCStatus {
|
||||||
Pending,
|
Pending = 0,
|
||||||
Completed,
|
Completed = 1,
|
||||||
Deleted,
|
Deleted = 2,
|
||||||
Recurring,
|
Recurring = 3,
|
||||||
/// Unknown signifies a status in the task DB that was not
|
Unknown = -1,
|
||||||
/// recognized.
|
|
||||||
Unknown,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<TCStatus> for Status {
|
impl From<TCStatus> for Status {
|
||||||
|
|
|
@ -4,6 +4,10 @@ use std::ffi::{CStr, CString, OsString};
|
||||||
use std::os::raw::c_char;
|
use std::os::raw::c_char;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 200)]
|
||||||
|
/// ***** TCString *****
|
||||||
|
///
|
||||||
/// TCString supports passing strings into and out of the TaskChampion API.
|
/// TCString supports passing strings into and out of the TaskChampion API.
|
||||||
///
|
///
|
||||||
/// # Rust Strings and C Strings
|
/// # Rust Strings and C Strings
|
||||||
|
@ -41,7 +45,15 @@ use std::path::PathBuf;
|
||||||
/// for such a value.
|
/// for such a value.
|
||||||
///
|
///
|
||||||
/// TCString is not threadsafe.
|
/// TCString is not threadsafe.
|
||||||
/// cbindgen:field-names=[ptr, _u1, _u2, _u3]
|
///
|
||||||
|
/// ```c
|
||||||
|
/// typedef struct TCString {
|
||||||
|
/// void *ptr; // opaque, but may be checked for NULL
|
||||||
|
/// size_t _u1; // reserved
|
||||||
|
/// size_t _u2; // reserved
|
||||||
|
/// uint8_t _u3; // reserved
|
||||||
|
/// } TCString;
|
||||||
|
/// ```
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct TCString {
|
pub struct TCString {
|
||||||
// defined based on the type
|
// defined based on the type
|
||||||
|
@ -360,19 +372,36 @@ where
|
||||||
rv
|
rv
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 210)]
|
||||||
|
/// ***** TCStringList *****
|
||||||
|
///
|
||||||
/// TCStringList represents a list of strings.
|
/// TCStringList represents a list of strings.
|
||||||
///
|
///
|
||||||
/// The content of this struct must be treated as read-only.
|
/// The content of this struct must be treated as read-only.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// typedef struct TCStringList {
|
||||||
|
/// // number of strings in items
|
||||||
|
/// size_t len;
|
||||||
|
/// // reserved
|
||||||
|
/// size_t _u1;
|
||||||
|
/// // TCStringList representing each string. These remain owned by the TCStringList instance and will
|
||||||
|
/// // be freed by tc_string_list_free. This pointer is never NULL for a valid TCStringList, and the
|
||||||
|
/// // *TCStringList at indexes 0..len-1 are not NULL.
|
||||||
|
/// struct TCString *items;
|
||||||
|
/// } TCStringList;
|
||||||
|
/// ```
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct TCStringList {
|
pub struct TCStringList {
|
||||||
/// number of strings in items
|
/// number of strings in items
|
||||||
len: libc::size_t,
|
len: libc::size_t,
|
||||||
|
|
||||||
/// total size of items (internal use only)
|
/// total size of items (internal use only)
|
||||||
_capacity: libc::size_t,
|
capacity: libc::size_t,
|
||||||
|
|
||||||
/// TCStringList representing each string. these remain owned by the TCStringList instance and will
|
/// Array of strings. These remain owned by the TCStringList instance and will be freed by
|
||||||
/// be freed by tc_string_list_free. This pointer is never NULL for a valid TCStringList, and the
|
/// tc_string_list_free. This pointer is never NULL for a valid TCStringList, and the
|
||||||
/// *TCStringList at indexes 0..len-1 are not NULL.
|
/// *TCStringList at indexes 0..len-1 are not NULL.
|
||||||
items: *mut TCString,
|
items: *mut TCString,
|
||||||
}
|
}
|
||||||
|
@ -383,7 +412,7 @@ impl CList for TCStringList {
|
||||||
unsafe fn from_raw_parts(items: *mut Self::Element, len: usize, cap: usize) -> Self {
|
unsafe fn from_raw_parts(items: *mut Self::Element, len: usize, cap: usize) -> Self {
|
||||||
TCStringList {
|
TCStringList {
|
||||||
len,
|
len,
|
||||||
_capacity: cap,
|
capacity: cap,
|
||||||
items,
|
items,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -398,10 +427,12 @@ impl CList for TCStringList {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn into_raw_parts(self) -> (*mut Self::Element, usize, usize) {
|
fn into_raw_parts(self) -> (*mut Self::Element, usize, usize) {
|
||||||
(self.items, self.len, self._capacity)
|
(self.items, self.len, self.capacity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 201)]
|
||||||
/// Create a new TCString referencing the given C string. The C string must remain valid and
|
/// Create a new TCString referencing the given C string. The C string must remain valid and
|
||||||
/// unchanged until after the TCString is freed. It's typically easiest to ensure this by using a
|
/// unchanged until after the TCString is freed. It's typically easiest to ensure this by using a
|
||||||
/// static string.
|
/// static string.
|
||||||
|
@ -416,6 +447,10 @@ impl CList for TCStringList {
|
||||||
/// tc_task_annotate(task, tc_string_borrow(url)); // TCString created, passed, and freed
|
/// tc_task_annotate(task, tc_string_borrow(url)); // TCString created, passed, and freed
|
||||||
/// free(url); // string is no longer referenced and can be freed
|
/// free(url); // string is no longer referenced and can be freed
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C struct TCString tc_string_borrow(const char *cstr);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_string_borrow(cstr: *const libc::c_char) -> TCString {
|
pub unsafe extern "C" fn tc_string_borrow(cstr: *const libc::c_char) -> TCString {
|
||||||
debug_assert!(!cstr.is_null());
|
debug_assert!(!cstr.is_null());
|
||||||
|
@ -430,8 +465,14 @@ pub unsafe extern "C" fn tc_string_borrow(cstr: *const libc::c_char) -> TCString
|
||||||
unsafe { TCString::return_val(RustString::CStr(cstr)) }
|
unsafe { TCString::return_val(RustString::CStr(cstr)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 201)]
|
||||||
/// Create a new TCString by cloning the content of the given C string. The resulting TCString
|
/// Create a new TCString by cloning the content of the given C string. The resulting TCString
|
||||||
/// is independent of the given string, which can be freed or overwritten immediately.
|
/// is independent of the given string, which can be freed or overwritten immediately.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C struct TCString tc_string_clone(const char *cstr);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_string_clone(cstr: *const libc::c_char) -> TCString {
|
pub unsafe extern "C" fn tc_string_clone(cstr: *const libc::c_char) -> TCString {
|
||||||
debug_assert!(!cstr.is_null());
|
debug_assert!(!cstr.is_null());
|
||||||
|
@ -447,6 +488,8 @@ pub unsafe extern "C" fn tc_string_clone(cstr: *const libc::c_char) -> TCString
|
||||||
unsafe { TCString::return_val(RustString::CString(cstring)) }
|
unsafe { TCString::return_val(RustString::CString(cstring)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 201)]
|
||||||
/// Create a new TCString containing the given string with the given length. This allows creation
|
/// Create a new TCString containing the given string with the given length. This allows creation
|
||||||
/// of strings containing embedded NUL characters. As with `tc_string_clone`, the resulting
|
/// of strings containing embedded NUL characters. As with `tc_string_clone`, the resulting
|
||||||
/// TCString is independent of the passed buffer, which may be reused or freed immediately.
|
/// TCString is independent of the passed buffer, which may be reused or freed immediately.
|
||||||
|
@ -454,6 +497,10 @@ pub unsafe extern "C" fn tc_string_clone(cstr: *const libc::c_char) -> TCString
|
||||||
/// The length should _not_ include any trailing NUL.
|
/// The length should _not_ include any trailing NUL.
|
||||||
///
|
///
|
||||||
/// The given length must be less than half the maximum value of usize.
|
/// The given length must be less than half the maximum value of usize.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C struct TCString tc_string_clone_with_len(const char *buf, size_t len);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_string_clone_with_len(
|
pub unsafe extern "C" fn tc_string_clone_with_len(
|
||||||
buf: *const libc::c_char,
|
buf: *const libc::c_char,
|
||||||
|
@ -477,6 +524,8 @@ pub unsafe extern "C" fn tc_string_clone_with_len(
|
||||||
unsafe { TCString::return_val(RustString::Bytes(vec)) }
|
unsafe { TCString::return_val(RustString::Bytes(vec)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 201)]
|
||||||
/// Get the content of the string as a regular C string. The given string must be valid. The
|
/// Get the content of the string as a regular C string. The given string must be valid. The
|
||||||
/// returned value is NULL if the string contains NUL bytes or (in some cases) invalid UTF-8. The
|
/// returned value is NULL if the string contains NUL bytes or (in some cases) invalid UTF-8. The
|
||||||
/// returned C string is valid until the TCString is freed or passed to another TC API function.
|
/// returned C string is valid until the TCString is freed or passed to another TC API function.
|
||||||
|
@ -488,6 +537,10 @@ pub unsafe extern "C" fn tc_string_clone_with_len(
|
||||||
/// terminator. The pointer must not be NULL.
|
/// terminator. The pointer must not be NULL.
|
||||||
///
|
///
|
||||||
/// This function does _not_ take ownership of the TCString.
|
/// This function does _not_ take ownership of the TCString.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C const char *tc_string_content(const struct TCString *tcstring);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_string_content(tcstring: *const TCString) -> *const libc::c_char {
|
pub unsafe extern "C" fn tc_string_content(tcstring: *const TCString) -> *const libc::c_char {
|
||||||
// SAFETY;
|
// SAFETY;
|
||||||
|
@ -514,6 +567,8 @@ pub unsafe extern "C" fn tc_string_content(tcstring: *const TCString) -> *const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 201)]
|
||||||
/// Get the content of the string as a pointer and length. The given string must not be NULL.
|
/// Get the content of the string as a pointer and length. The given string must not be NULL.
|
||||||
/// This function can return any string, even one including NUL bytes or invalid UTF-8. The
|
/// This function can return any string, even one including NUL bytes or invalid UTF-8. The
|
||||||
/// returned buffer is valid until the TCString is freed or passed to another TaskChampio
|
/// returned buffer is valid until the TCString is freed or passed to another TaskChampio
|
||||||
|
@ -523,6 +578,10 @@ pub unsafe extern "C" fn tc_string_content(tcstring: *const TCString) -> *const
|
||||||
/// terminator. The pointer must not be NULL.
|
/// terminator. The pointer must not be NULL.
|
||||||
///
|
///
|
||||||
/// This function does _not_ take ownership of the TCString.
|
/// This function does _not_ take ownership of the TCString.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C const char *tc_string_content_with_len(const struct TCString *tcstring, size_t *len_out);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_string_content_with_len(
|
pub unsafe extern "C" fn tc_string_content_with_len(
|
||||||
tcstring: *const TCString,
|
tcstring: *const TCString,
|
||||||
|
@ -546,8 +605,14 @@ pub unsafe extern "C" fn tc_string_content_with_len(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 201)]
|
||||||
/// Free a TCString. The given string must not be NULL. The string must not be used
|
/// Free a TCString. The given string must not be NULL. The string must not be used
|
||||||
/// after this function returns, and must not be freed more than once.
|
/// after this function returns, and must not be freed more than once.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C void tc_string_free(struct TCString *tcstring);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_string_free(tcstring: *mut TCString) {
|
pub unsafe extern "C" fn tc_string_free(tcstring: *mut TCString) {
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
|
@ -556,10 +621,16 @@ pub unsafe extern "C" fn tc_string_free(tcstring: *mut TCString) {
|
||||||
drop(unsafe { TCString::take_val_from_arg(tcstring, TCString::default()) });
|
drop(unsafe { TCString::take_val_from_arg(tcstring, TCString::default()) });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 211)]
|
||||||
/// Free a TCStringList instance. The instance, and all TCStringList it contains, must not be used after
|
/// Free a TCStringList instance. The instance, and all TCStringList it contains, must not be used after
|
||||||
/// this call.
|
/// this call.
|
||||||
///
|
///
|
||||||
/// When this call returns, the `items` pointer will be NULL, signalling an invalid TCStringList.
|
/// When this call returns, the `items` pointer will be NULL, signalling an invalid TCStringList.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C void tc_string_list_free(struct TCStringList *tcstrings);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_string_list_free(tcstrings: *mut TCStringList) {
|
pub unsafe extern "C" fn tc_string_list_free(tcstrings: *mut TCStringList) {
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
|
@ -579,7 +650,7 @@ mod test {
|
||||||
let tcstrings = unsafe { TCStringList::return_val(Vec::new()) };
|
let tcstrings = unsafe { TCStringList::return_val(Vec::new()) };
|
||||||
assert!(!tcstrings.items.is_null());
|
assert!(!tcstrings.items.is_null());
|
||||||
assert_eq!(tcstrings.len, 0);
|
assert_eq!(tcstrings.len, 0);
|
||||||
assert_eq!(tcstrings._capacity, 0);
|
assert_eq!(tcstrings.capacity, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -589,7 +660,7 @@ mod test {
|
||||||
unsafe { tc_string_list_free(&mut tcstrings) };
|
unsafe { tc_string_list_free(&mut tcstrings) };
|
||||||
assert!(tcstrings.items.is_null());
|
assert!(tcstrings.items.is_null());
|
||||||
assert_eq!(tcstrings.len, 0);
|
assert_eq!(tcstrings.len, 0);
|
||||||
assert_eq!(tcstrings._capacity, 0);
|
assert_eq!(tcstrings.capacity, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const INVALID_UTF8: &[u8] = b"abc\xf0\x28\x8c\x28";
|
const INVALID_UTF8: &[u8] = b"abc\xf0\x28\x8c\x28";
|
||||||
|
|
|
@ -7,6 +7,10 @@ use std::ptr::NonNull;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use taskchampion::{utc_timestamp, Annotation, Tag, Task, TaskMut, Uuid};
|
use taskchampion::{utc_timestamp, Annotation, Tag, Task, TaskMut, Uuid};
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1000)]
|
||||||
|
/// ***** TCTask *****
|
||||||
|
///
|
||||||
/// A task, as publicly exposed by this library.
|
/// A task, as publicly exposed by this library.
|
||||||
///
|
///
|
||||||
/// A task begins in "immutable" mode. It must be converted to "mutable" mode
|
/// A task begins in "immutable" mode. It must be converted to "mutable" mode
|
||||||
|
@ -36,6 +40,10 @@ use taskchampion::{utc_timestamp, Annotation, Tag, Task, TaskMut, Uuid};
|
||||||
/// Once passed to tc_task_free, a `*TCTask` becomes invalid and must not be used again.
|
/// Once passed to tc_task_free, a `*TCTask` becomes invalid and must not be used again.
|
||||||
///
|
///
|
||||||
/// TCTasks are not threadsafe.
|
/// TCTasks are not threadsafe.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// typedef struct TCTask TCTask;
|
||||||
|
/// ```
|
||||||
pub struct TCTask {
|
pub struct TCTask {
|
||||||
/// The wrapped Task or TaskMut
|
/// The wrapped Task or TaskMut
|
||||||
inner: Inner,
|
inner: Inner,
|
||||||
|
@ -168,23 +176,40 @@ impl TryFrom<RustString<'static>> for Tag {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1010)]
|
||||||
|
/// ***** TCTaskList *****
|
||||||
|
///
|
||||||
/// TCTaskList represents a list of tasks.
|
/// TCTaskList represents a list of tasks.
|
||||||
///
|
///
|
||||||
/// The content of this struct must be treated as read-only: no fields or anything they reference
|
/// The content of this struct must be treated as read-only: no fields or anything they reference
|
||||||
/// should be modified directly by C code.
|
/// should be modified directly by C code.
|
||||||
///
|
///
|
||||||
/// When an item is taken from this list, its pointer in `items` is set to NULL.
|
/// When an item is taken from this list, its pointer in `items` is set to NULL.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// typedef struct TCTaskList {
|
||||||
|
/// // number of tasks in items
|
||||||
|
/// size_t len;
|
||||||
|
/// // reserved
|
||||||
|
/// size_t _u1;
|
||||||
|
/// // Array of pointers representing each task. These remain owned by the TCTaskList instance and
|
||||||
|
/// // will be freed by tc_task_list_free. This pointer is never NULL for a valid TCTaskList.
|
||||||
|
/// // Pointers in the array may be NULL after `tc_task_list_take`.
|
||||||
|
/// struct TCTask **items;
|
||||||
|
/// } TCTaskList;
|
||||||
|
/// ```
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct TCTaskList {
|
pub struct TCTaskList {
|
||||||
/// number of tasks in items
|
/// number of tasks in items
|
||||||
len: libc::size_t,
|
len: libc::size_t,
|
||||||
|
|
||||||
/// total size of items (internal use only)
|
/// total size of items (internal use only)
|
||||||
_capacity: libc::size_t,
|
capacity: libc::size_t,
|
||||||
|
|
||||||
/// array of pointers representing each task. these remain owned by the TCTaskList instance and
|
/// Array of pointers representing each task. These remain owned by the TCTaskList instance and
|
||||||
/// will be freed by tc_task_list_free. This pointer is never NULL for a valid TCTaskList,
|
/// will be freed by tc_task_list_free. This pointer is never NULL for a valid TCTaskList.
|
||||||
/// and the *TCTaskList at indexes 0..len-1 are not NULL.
|
/// Pointers in the array may be NULL after `tc_task_list_take`.
|
||||||
items: *mut Option<NonNull<TCTask>>,
|
items: *mut Option<NonNull<TCTask>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +219,7 @@ impl CList for TCTaskList {
|
||||||
unsafe fn from_raw_parts(items: *mut Self::Element, len: usize, cap: usize) -> Self {
|
unsafe fn from_raw_parts(items: *mut Self::Element, len: usize, cap: usize) -> Self {
|
||||||
TCTaskList {
|
TCTaskList {
|
||||||
len,
|
len,
|
||||||
_capacity: cap,
|
capacity: cap,
|
||||||
items,
|
items,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,55 +234,18 @@ impl CList for TCTaskList {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn into_raw_parts(self) -> (*mut Self::Element, usize, usize) {
|
fn into_raw_parts(self) -> (*mut Self::Element, usize, usize) {
|
||||||
(self.items, self.len, self._capacity)
|
(self.items, self.len, self.capacity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert an immutable task into a mutable task.
|
#[ffizz_header::item]
|
||||||
///
|
#[ffizz(order = 1001)]
|
||||||
/// The task must not be NULL. It is modified in-place, and becomes mutable.
|
/// Get a task's UUID.
|
||||||
///
|
|
||||||
/// The replica must not be NULL. After this function returns, the replica _cannot be used at all_
|
|
||||||
/// until this task is made immutable again. This implies that it is not allowed for more than one
|
|
||||||
/// task associated with a replica to be mutable at any time.
|
|
||||||
///
|
|
||||||
/// Typical mutation of tasks is bracketed with `tc_task_to_mut` and `tc_task_to_immut`:
|
|
||||||
///
|
///
|
||||||
/// ```c
|
/// ```c
|
||||||
/// tc_task_to_mut(task, rep);
|
/// EXTERN_C struct TCUuid tc_task_get_uuid(struct TCTask *task);
|
||||||
/// success = tc_task_done(task);
|
|
||||||
/// tc_task_to_immut(task, rep);
|
|
||||||
/// if (!success) { ... }
|
|
||||||
/// ```
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_to_mut(task: *mut TCTask, tcreplica: *mut TCReplica) {
|
|
||||||
// SAFETY:
|
|
||||||
// - task is not null (promised by caller)
|
|
||||||
// - task outlives 'a (promised by caller)
|
|
||||||
let tctask: &mut TCTask = unsafe { TCTask::from_ptr_arg_ref_mut(task) };
|
|
||||||
// SAFETY:
|
|
||||||
// - tcreplica is not NULL (promised by caller)
|
|
||||||
// - tcreplica lives until later call to to_immut via tc_task_to_immut (promised by caller,
|
|
||||||
// who cannot call tc_replica_free during this time)
|
|
||||||
unsafe { tctask.to_mut(tcreplica) };
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert a mutable task into an immutable task.
|
|
||||||
///
|
|
||||||
/// The task must not be NULL. It is modified in-place, and becomes immutable.
|
|
||||||
///
|
|
||||||
/// The replica passed to `tc_task_to_mut` may be used freely after this call.
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn tc_task_to_immut(task: *mut TCTask) {
|
|
||||||
// SAFETY:
|
|
||||||
// - task is not null (promised by caller)
|
|
||||||
// - task outlives 'a (promised by caller)
|
|
||||||
let tctask: &mut TCTask = unsafe { TCTask::from_ptr_arg_ref_mut(task) };
|
|
||||||
tctask.to_immut();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get a task's UUID.
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn tc_task_get_uuid(task: *mut TCTask) -> TCUuid {
|
pub unsafe extern "C" fn tc_task_get_uuid(task: *mut TCTask) -> TCUuid {
|
||||||
wrap(task, |task| {
|
wrap(task, |task| {
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
|
@ -266,15 +254,27 @@ pub unsafe extern "C" fn tc_task_get_uuid(task: *mut TCTask) -> TCUuid {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1001)]
|
||||||
/// Get a task's status.
|
/// Get a task's status.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C enum TCStatus tc_task_get_status(struct TCTask *task);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_get_status(task: *mut TCTask) -> TCStatus {
|
pub unsafe extern "C" fn tc_task_get_status(task: *mut TCTask) -> TCStatus {
|
||||||
wrap(task, |task| task.get_status().into())
|
wrap(task, |task| task.get_status().into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1001)]
|
||||||
/// Get the underlying key/value pairs for this task. The returned TCKVList is
|
/// Get the underlying key/value pairs for this task. The returned TCKVList is
|
||||||
/// a "snapshot" of the task and will not be updated if the task is subsequently
|
/// a "snapshot" of the task and will not be updated if the task is subsequently
|
||||||
/// modified. It is the caller's responsibility to free the TCKVList.
|
/// modified. It is the caller's responsibility to free the TCKVList.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C struct TCKVList tc_task_get_taskmap(struct TCTask *task);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_get_taskmap(task: *mut TCTask) -> TCKVList {
|
pub unsafe extern "C" fn tc_task_get_taskmap(task: *mut TCTask) -> TCKVList {
|
||||||
wrap(task, |task| {
|
wrap(task, |task| {
|
||||||
|
@ -293,7 +293,13 @@ pub unsafe extern "C" fn tc_task_get_taskmap(task: *mut TCTask) -> TCKVList {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1001)]
|
||||||
/// Get a task's description.
|
/// Get a task's description.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C struct TCString tc_task_get_description(struct TCTask *task);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_get_description(task: *mut TCTask) -> TCString {
|
pub unsafe extern "C" fn tc_task_get_description(task: *mut TCTask) -> TCString {
|
||||||
wrap(task, |task| {
|
wrap(task, |task| {
|
||||||
|
@ -304,8 +310,14 @@ pub unsafe extern "C" fn tc_task_get_description(task: *mut TCTask) -> TCString
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1001)]
|
||||||
/// Get a task property's value, or NULL if the task has no such property, (including if the
|
/// Get a task property's value, or NULL if the task has no such property, (including if the
|
||||||
/// property name is not valid utf-8).
|
/// property name is not valid utf-8).
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C struct TCString tc_task_get_value(struct TCTask *task, struct TCString property);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_get_value(task: *mut TCTask, property: TCString) -> TCString {
|
pub unsafe extern "C" fn tc_task_get_value(task: *mut TCTask, property: TCString) -> TCString {
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
|
@ -325,50 +337,98 @@ pub unsafe extern "C" fn tc_task_get_value(task: *mut TCTask, property: TCString
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1001)]
|
||||||
/// Get the entry timestamp for a task (when it was created), or 0 if not set.
|
/// Get the entry timestamp for a task (when it was created), or 0 if not set.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C time_t tc_task_get_entry(struct TCTask *task);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_get_entry(task: *mut TCTask) -> libc::time_t {
|
pub unsafe extern "C" fn tc_task_get_entry(task: *mut TCTask) -> libc::time_t {
|
||||||
wrap(task, |task| libc::time_t::as_ctype(task.get_entry()))
|
wrap(task, |task| libc::time_t::as_ctype(task.get_entry()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1001)]
|
||||||
/// Get the wait timestamp for a task, or 0 if not set.
|
/// Get the wait timestamp for a task, or 0 if not set.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C time_t tc_task_get_wait(struct TCTask *task);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_get_wait(task: *mut TCTask) -> libc::time_t {
|
pub unsafe extern "C" fn tc_task_get_wait(task: *mut TCTask) -> libc::time_t {
|
||||||
wrap(task, |task| libc::time_t::as_ctype(task.get_wait()))
|
wrap(task, |task| libc::time_t::as_ctype(task.get_wait()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1001)]
|
||||||
/// Get the modified timestamp for a task, or 0 if not set.
|
/// Get the modified timestamp for a task, or 0 if not set.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C time_t tc_task_get_modified(struct TCTask *task);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_get_modified(task: *mut TCTask) -> libc::time_t {
|
pub unsafe extern "C" fn tc_task_get_modified(task: *mut TCTask) -> libc::time_t {
|
||||||
wrap(task, |task| libc::time_t::as_ctype(task.get_modified()))
|
wrap(task, |task| libc::time_t::as_ctype(task.get_modified()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1001)]
|
||||||
/// Check if a task is waiting.
|
/// Check if a task is waiting.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C bool tc_task_is_waiting(struct TCTask *task);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_is_waiting(task: *mut TCTask) -> bool {
|
pub unsafe extern "C" fn tc_task_is_waiting(task: *mut TCTask) -> bool {
|
||||||
wrap(task, |task| task.is_waiting())
|
wrap(task, |task| task.is_waiting())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1001)]
|
||||||
/// Check if a task is active (started and not stopped).
|
/// Check if a task is active (started and not stopped).
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C bool tc_task_is_active(struct TCTask *task);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_is_active(task: *mut TCTask) -> bool {
|
pub unsafe extern "C" fn tc_task_is_active(task: *mut TCTask) -> bool {
|
||||||
wrap(task, |task| task.is_active())
|
wrap(task, |task| task.is_active())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1001)]
|
||||||
/// Check if a task is blocked (depends on at least one other task).
|
/// Check if a task is blocked (depends on at least one other task).
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C bool tc_task_is_blocked(struct TCTask *task);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_is_blocked(task: *mut TCTask) -> bool {
|
pub unsafe extern "C" fn tc_task_is_blocked(task: *mut TCTask) -> bool {
|
||||||
wrap(task, |task| task.is_blocked())
|
wrap(task, |task| task.is_blocked())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1001)]
|
||||||
/// Check if a task is blocking (at least one other task depends on it).
|
/// Check if a task is blocking (at least one other task depends on it).
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C bool tc_task_is_blocking(struct TCTask *task);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_is_blocking(task: *mut TCTask) -> bool {
|
pub unsafe extern "C" fn tc_task_is_blocking(task: *mut TCTask) -> bool {
|
||||||
wrap(task, |task| task.is_blocking())
|
wrap(task, |task| task.is_blocking())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1001)]
|
||||||
/// Check if a task has the given tag. If the tag is invalid, this function will return false, as
|
/// Check if a task has the given tag. If the tag is invalid, this function will return false, as
|
||||||
/// that (invalid) tag is not present. No error will be reported via `tc_task_error`.
|
/// that (invalid) tag is not present. No error will be reported via `tc_task_error`.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C bool tc_task_has_tag(struct TCTask *task, struct TCString tag);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_has_tag(task: *mut TCTask, tag: TCString) -> bool {
|
pub unsafe extern "C" fn tc_task_has_tag(task: *mut TCTask, tag: TCString) -> bool {
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
|
@ -384,10 +444,16 @@ pub unsafe extern "C" fn tc_task_has_tag(task: *mut TCTask, tag: TCString) -> bo
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1001)]
|
||||||
/// Get the tags for the task.
|
/// Get the tags for the task.
|
||||||
///
|
///
|
||||||
/// The caller must free the returned TCStringList instance. The TCStringList instance does not
|
/// The caller must free the returned TCStringList instance. The TCStringList instance does not
|
||||||
/// reference the task and the two may be freed in any order.
|
/// reference the task and the two may be freed in any order.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C struct TCStringList tc_task_get_tags(struct TCTask *task);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_get_tags(task: *mut TCTask) -> TCStringList {
|
pub unsafe extern "C" fn tc_task_get_tags(task: *mut TCTask) -> TCStringList {
|
||||||
wrap(task, |task| {
|
wrap(task, |task| {
|
||||||
|
@ -405,10 +471,16 @@ pub unsafe extern "C" fn tc_task_get_tags(task: *mut TCTask) -> TCStringList {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1001)]
|
||||||
/// Get the annotations for the task.
|
/// Get the annotations for the task.
|
||||||
///
|
///
|
||||||
/// The caller must free the returned TCAnnotationList instance. The TCStringList instance does not
|
/// The caller must free the returned TCAnnotationList instance. The TCStringList instance does not
|
||||||
/// reference the task and the two may be freed in any order.
|
/// reference the task and the two may be freed in any order.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C struct TCAnnotationList tc_task_get_annotations(struct TCTask *task);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_get_annotations(task: *mut TCTask) -> TCAnnotationList {
|
pub unsafe extern "C" fn tc_task_get_annotations(task: *mut TCTask) -> TCAnnotationList {
|
||||||
wrap(task, |task| {
|
wrap(task, |task| {
|
||||||
|
@ -425,9 +497,15 @@ pub unsafe extern "C" fn tc_task_get_annotations(task: *mut TCTask) -> TCAnnotat
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1001)]
|
||||||
/// Get the named UDA from the task.
|
/// Get the named UDA from the task.
|
||||||
///
|
///
|
||||||
/// Returns a TCString with NULL ptr field if the UDA does not exist.
|
/// Returns a TCString with NULL ptr field if the UDA does not exist.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C struct TCString tc_task_get_uda(struct TCTask *task, struct TCString ns, struct TCString key);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_get_uda(
|
pub unsafe extern "C" fn tc_task_get_uda(
|
||||||
task: *mut TCTask,
|
task: *mut TCTask,
|
||||||
|
@ -452,9 +530,15 @@ pub unsafe extern "C" fn tc_task_get_uda(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1001)]
|
||||||
/// Get the named legacy UDA from the task.
|
/// Get the named legacy UDA from the task.
|
||||||
///
|
///
|
||||||
/// Returns NULL if the UDA does not exist.
|
/// Returns NULL if the UDA does not exist.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C struct TCString tc_task_get_legacy_uda(struct TCTask *task, struct TCString key);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_get_legacy_uda(task: *mut TCTask, key: TCString) -> TCString {
|
pub unsafe extern "C" fn tc_task_get_legacy_uda(task: *mut TCTask, key: TCString) -> TCString {
|
||||||
wrap(task, |task| {
|
wrap(task, |task| {
|
||||||
|
@ -472,9 +556,15 @@ pub unsafe extern "C" fn tc_task_get_legacy_uda(task: *mut TCTask, key: TCString
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1001)]
|
||||||
/// Get all UDAs for this task.
|
/// Get all UDAs for this task.
|
||||||
///
|
///
|
||||||
/// Legacy UDAs are represented with an empty string in the ns field.
|
/// Legacy UDAs are represented with an empty string in the ns field.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C struct TCUdaList tc_task_get_udas(struct TCTask *task);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_get_udas(task: *mut TCTask) -> TCUdaList {
|
pub unsafe extern "C" fn tc_task_get_udas(task: *mut TCTask) -> TCUdaList {
|
||||||
wrap(task, |task| {
|
wrap(task, |task| {
|
||||||
|
@ -498,10 +588,16 @@ pub unsafe extern "C" fn tc_task_get_udas(task: *mut TCTask) -> TCUdaList {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1001)]
|
||||||
/// Get all UDAs for this task.
|
/// Get all UDAs for this task.
|
||||||
///
|
///
|
||||||
/// All TCUdas in this list have a NULL ns field. The entire UDA key is
|
/// All TCUdas in this list have a NULL ns field. The entire UDA key is
|
||||||
/// included in the key field. The caller must free the returned list.
|
/// included in the key field. The caller must free the returned list.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C struct TCUdaList tc_task_get_legacy_udas(struct TCTask *task);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_get_legacy_udas(task: *mut TCTask) -> TCUdaList {
|
pub unsafe extern "C" fn tc_task_get_legacy_udas(task: *mut TCTask) -> TCUdaList {
|
||||||
wrap(task, |task| {
|
wrap(task, |task| {
|
||||||
|
@ -525,7 +621,70 @@ pub unsafe extern "C" fn tc_task_get_legacy_udas(task: *mut TCTask) -> TCUdaList
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1001)]
|
||||||
|
/// Get all dependencies for a task.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C struct TCUuidList tc_task_get_dependencies(struct TCTask *task);
|
||||||
|
/// ```
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn tc_task_get_dependencies(task: *mut TCTask) -> TCUuidList {
|
||||||
|
wrap(task, |task| {
|
||||||
|
let vec: Vec<TCUuid> = task
|
||||||
|
.get_dependencies()
|
||||||
|
.map(|u| {
|
||||||
|
// SAFETY:
|
||||||
|
// - value is not allocated
|
||||||
|
unsafe { TCUuid::return_val(u) }
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
// SAFETY:
|
||||||
|
// - caller will free this list
|
||||||
|
unsafe { TCUuidList::return_val(vec) }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1002)]
|
||||||
|
/// Convert an immutable task into a mutable task.
|
||||||
|
///
|
||||||
|
/// The task must not be NULL. It is modified in-place, and becomes mutable.
|
||||||
|
///
|
||||||
|
/// The replica must not be NULL. After this function returns, the replica _cannot be used at all_
|
||||||
|
/// until this task is made immutable again. This implies that it is not allowed for more than one
|
||||||
|
/// task associated with a replica to be mutable at any time.
|
||||||
|
///
|
||||||
|
/// Typical mutation of tasks is bracketed with `tc_task_to_mut` and `tc_task_to_immut`:
|
||||||
|
///
|
||||||
|
/// tc_task_to_mut(task, rep);
|
||||||
|
/// success = tc_task_done(task);
|
||||||
|
/// tc_task_to_immut(task, rep);
|
||||||
|
/// if (!success) { ... }
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C void tc_task_to_mut(struct TCTask *task, struct TCReplica *tcreplica);
|
||||||
|
/// ```
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn tc_task_to_mut(task: *mut TCTask, tcreplica: *mut TCReplica) {
|
||||||
|
// SAFETY:
|
||||||
|
// - task is not null (promised by caller)
|
||||||
|
// - task outlives 'a (promised by caller)
|
||||||
|
let tctask: &mut TCTask = unsafe { TCTask::from_ptr_arg_ref_mut(task) };
|
||||||
|
// SAFETY:
|
||||||
|
// - tcreplica is not NULL (promised by caller)
|
||||||
|
// - tcreplica lives until later call to to_immut via tc_task_to_immut (promised by caller,
|
||||||
|
// who cannot call tc_replica_free during this time)
|
||||||
|
unsafe { tctask.to_mut(tcreplica) };
|
||||||
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1003)]
|
||||||
/// Set a mutable task's status.
|
/// Set a mutable task's status.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C TCResult tc_task_set_status(struct TCTask *task, enum TCStatus status);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_set_status(task: *mut TCTask, status: TCStatus) -> TCResult {
|
pub unsafe extern "C" fn tc_task_set_status(task: *mut TCTask, status: TCStatus) -> TCResult {
|
||||||
wrap_mut(
|
wrap_mut(
|
||||||
|
@ -538,7 +697,13 @@ pub unsafe extern "C" fn tc_task_set_status(task: *mut TCTask, status: TCStatus)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1003)]
|
||||||
/// Set a mutable task's property value by name. If value.ptr is NULL, the property is removed.
|
/// Set a mutable task's property value by name. If value.ptr is NULL, the property is removed.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C TCResult tc_task_set_value(struct TCTask *task, struct TCString property, struct TCString value);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_set_value(
|
pub unsafe extern "C" fn tc_task_set_value(
|
||||||
task: *mut TCTask,
|
task: *mut TCTask,
|
||||||
|
@ -572,7 +737,13 @@ pub unsafe extern "C" fn tc_task_set_value(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1003)]
|
||||||
/// Set a mutable task's description.
|
/// Set a mutable task's description.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C TCResult tc_task_set_description(struct TCTask *task, struct TCString description);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_set_description(
|
pub unsafe extern "C" fn tc_task_set_description(
|
||||||
task: *mut TCTask,
|
task: *mut TCTask,
|
||||||
|
@ -592,8 +763,14 @@ pub unsafe extern "C" fn tc_task_set_description(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1003)]
|
||||||
/// Set a mutable task's entry (creation time). Pass entry=0 to unset
|
/// Set a mutable task's entry (creation time). Pass entry=0 to unset
|
||||||
/// the entry field.
|
/// the entry field.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C TCResult tc_task_set_entry(struct TCTask *task, time_t entry);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_set_entry(task: *mut TCTask, entry: libc::time_t) -> TCResult {
|
pub unsafe extern "C" fn tc_task_set_entry(task: *mut TCTask, entry: libc::time_t) -> TCResult {
|
||||||
wrap_mut(
|
wrap_mut(
|
||||||
|
@ -607,7 +784,13 @@ pub unsafe extern "C" fn tc_task_set_entry(task: *mut TCTask, entry: libc::time_
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1003)]
|
||||||
/// Set a mutable task's wait timestamp. Pass wait=0 to unset the wait field.
|
/// Set a mutable task's wait timestamp. Pass wait=0 to unset the wait field.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C TCResult tc_task_set_wait(struct TCTask *task, time_t wait);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_set_wait(task: *mut TCTask, wait: libc::time_t) -> TCResult {
|
pub unsafe extern "C" fn tc_task_set_wait(task: *mut TCTask, wait: libc::time_t) -> TCResult {
|
||||||
wrap_mut(
|
wrap_mut(
|
||||||
|
@ -621,7 +804,13 @@ pub unsafe extern "C" fn tc_task_set_wait(task: *mut TCTask, wait: libc::time_t)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1003)]
|
||||||
/// Set a mutable task's modified timestamp. The value cannot be zero.
|
/// Set a mutable task's modified timestamp. The value cannot be zero.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C TCResult tc_task_set_modified(struct TCTask *task, time_t modified);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_set_modified(
|
pub unsafe extern "C" fn tc_task_set_modified(
|
||||||
task: *mut TCTask,
|
task: *mut TCTask,
|
||||||
|
@ -641,7 +830,13 @@ pub unsafe extern "C" fn tc_task_set_modified(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1003)]
|
||||||
/// Start a task.
|
/// Start a task.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C TCResult tc_task_start(struct TCTask *task);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_start(task: *mut TCTask) -> TCResult {
|
pub unsafe extern "C" fn tc_task_start(task: *mut TCTask) -> TCResult {
|
||||||
wrap_mut(
|
wrap_mut(
|
||||||
|
@ -654,7 +849,13 @@ pub unsafe extern "C" fn tc_task_start(task: *mut TCTask) -> TCResult {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1003)]
|
||||||
/// Stop a task.
|
/// Stop a task.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C TCResult tc_task_stop(struct TCTask *task);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_stop(task: *mut TCTask) -> TCResult {
|
pub unsafe extern "C" fn tc_task_stop(task: *mut TCTask) -> TCResult {
|
||||||
wrap_mut(
|
wrap_mut(
|
||||||
|
@ -667,7 +868,13 @@ pub unsafe extern "C" fn tc_task_stop(task: *mut TCTask) -> TCResult {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1003)]
|
||||||
/// Mark a task as done.
|
/// Mark a task as done.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C TCResult tc_task_done(struct TCTask *task);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_done(task: *mut TCTask) -> TCResult {
|
pub unsafe extern "C" fn tc_task_done(task: *mut TCTask) -> TCResult {
|
||||||
wrap_mut(
|
wrap_mut(
|
||||||
|
@ -680,7 +887,13 @@ pub unsafe extern "C" fn tc_task_done(task: *mut TCTask) -> TCResult {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1003)]
|
||||||
/// Mark a task as deleted.
|
/// Mark a task as deleted.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C TCResult tc_task_delete(struct TCTask *task);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_delete(task: *mut TCTask) -> TCResult {
|
pub unsafe extern "C" fn tc_task_delete(task: *mut TCTask) -> TCResult {
|
||||||
wrap_mut(
|
wrap_mut(
|
||||||
|
@ -693,7 +906,13 @@ pub unsafe extern "C" fn tc_task_delete(task: *mut TCTask) -> TCResult {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1003)]
|
||||||
/// Add a tag to a mutable task.
|
/// Add a tag to a mutable task.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C TCResult tc_task_add_tag(struct TCTask *task, struct TCString tag);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_add_tag(task: *mut TCTask, tag: TCString) -> TCResult {
|
pub unsafe extern "C" fn tc_task_add_tag(task: *mut TCTask, tag: TCString) -> TCResult {
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
|
@ -711,7 +930,13 @@ pub unsafe extern "C" fn tc_task_add_tag(task: *mut TCTask, tag: TCString) -> TC
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1003)]
|
||||||
/// Remove a tag from a mutable task.
|
/// Remove a tag from a mutable task.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C TCResult tc_task_remove_tag(struct TCTask *task, struct TCString tag);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_remove_tag(task: *mut TCTask, tag: TCString) -> TCResult {
|
pub unsafe extern "C" fn tc_task_remove_tag(task: *mut TCTask, tag: TCString) -> TCResult {
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
|
@ -729,8 +954,14 @@ pub unsafe extern "C" fn tc_task_remove_tag(task: *mut TCTask, tag: TCString) ->
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1003)]
|
||||||
/// Add an annotation to a mutable task. This call takes ownership of the
|
/// Add an annotation to a mutable task. This call takes ownership of the
|
||||||
/// passed annotation, which must not be used after the call returns.
|
/// passed annotation, which must not be used after the call returns.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C TCResult tc_task_add_annotation(struct TCTask *task, struct TCAnnotation *annotation);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_add_annotation(
|
pub unsafe extern "C" fn tc_task_add_annotation(
|
||||||
task: *mut TCTask,
|
task: *mut TCTask,
|
||||||
|
@ -753,7 +984,13 @@ pub unsafe extern "C" fn tc_task_add_annotation(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1003)]
|
||||||
/// Remove an annotation from a mutable task.
|
/// Remove an annotation from a mutable task.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C TCResult tc_task_remove_annotation(struct TCTask *task, int64_t entry);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_remove_annotation(task: *mut TCTask, entry: i64) -> TCResult {
|
pub unsafe extern "C" fn tc_task_remove_annotation(task: *mut TCTask, entry: i64) -> TCResult {
|
||||||
wrap_mut(
|
wrap_mut(
|
||||||
|
@ -766,7 +1003,16 @@ pub unsafe extern "C" fn tc_task_remove_annotation(task: *mut TCTask, entry: i64
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1003)]
|
||||||
/// Set a UDA on a mutable task.
|
/// Set a UDA on a mutable task.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C TCResult tc_task_set_uda(struct TCTask *task,
|
||||||
|
/// struct TCString ns,
|
||||||
|
/// struct TCString key,
|
||||||
|
/// struct TCString value);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_set_uda(
|
pub unsafe extern "C" fn tc_task_set_uda(
|
||||||
task: *mut TCTask,
|
task: *mut TCTask,
|
||||||
|
@ -792,7 +1038,13 @@ pub unsafe extern "C" fn tc_task_set_uda(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1003)]
|
||||||
/// Remove a UDA fraom a mutable task.
|
/// Remove a UDA fraom a mutable task.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C TCResult tc_task_remove_uda(struct TCTask *task, struct TCString ns, struct TCString key);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_remove_uda(
|
pub unsafe extern "C" fn tc_task_remove_uda(
|
||||||
task: *mut TCTask,
|
task: *mut TCTask,
|
||||||
|
@ -815,7 +1067,13 @@ pub unsafe extern "C" fn tc_task_remove_uda(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1003)]
|
||||||
/// Set a legacy UDA on a mutable task.
|
/// Set a legacy UDA on a mutable task.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C TCResult tc_task_set_legacy_uda(struct TCTask *task, struct TCString key, struct TCString value);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_set_legacy_uda(
|
pub unsafe extern "C" fn tc_task_set_legacy_uda(
|
||||||
task: *mut TCTask,
|
task: *mut TCTask,
|
||||||
|
@ -838,7 +1096,13 @@ pub unsafe extern "C" fn tc_task_set_legacy_uda(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1003)]
|
||||||
/// Remove a UDA fraom a mutable task.
|
/// Remove a UDA fraom a mutable task.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C TCResult tc_task_remove_legacy_uda(struct TCTask *task, struct TCString key);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_remove_legacy_uda(task: *mut TCTask, key: TCString) -> TCResult {
|
pub unsafe extern "C" fn tc_task_remove_legacy_uda(task: *mut TCTask, key: TCString) -> TCResult {
|
||||||
// safety:
|
// safety:
|
||||||
|
@ -855,25 +1119,13 @@ pub unsafe extern "C" fn tc_task_remove_legacy_uda(task: *mut TCTask, key: TCStr
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get all dependencies for a task.
|
#[ffizz_header::item]
|
||||||
#[no_mangle]
|
#[ffizz(order = 1003)]
|
||||||
pub unsafe extern "C" fn tc_task_get_dependencies(task: *mut TCTask) -> TCUuidList {
|
|
||||||
wrap(task, |task| {
|
|
||||||
let vec: Vec<TCUuid> = task
|
|
||||||
.get_dependencies()
|
|
||||||
.map(|u| {
|
|
||||||
// SAFETY:
|
|
||||||
// - value is not allocated
|
|
||||||
unsafe { TCUuid::return_val(u) }
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
// SAFETY:
|
|
||||||
// - caller will free this list
|
|
||||||
unsafe { TCUuidList::return_val(vec) }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add a dependency.
|
/// Add a dependency.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C TCResult tc_task_add_dependency(struct TCTask *task, struct TCUuid dep);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_add_dependency(task: *mut TCTask, dep: TCUuid) -> TCResult {
|
pub unsafe extern "C" fn tc_task_add_dependency(task: *mut TCTask, dep: TCUuid) -> TCResult {
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
|
@ -889,7 +1141,13 @@ pub unsafe extern "C" fn tc_task_add_dependency(task: *mut TCTask, dep: TCUuid)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1003)]
|
||||||
/// Remove a dependency.
|
/// Remove a dependency.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C TCResult tc_task_remove_dependency(struct TCTask *task, struct TCUuid dep);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_remove_dependency(task: *mut TCTask, dep: TCUuid) -> TCResult {
|
pub unsafe extern "C" fn tc_task_remove_dependency(task: *mut TCTask, dep: TCUuid) -> TCResult {
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
|
@ -905,9 +1163,35 @@ pub unsafe extern "C" fn tc_task_remove_dependency(task: *mut TCTask, dep: TCUui
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1004)]
|
||||||
|
/// Convert a mutable task into an immutable task.
|
||||||
|
///
|
||||||
|
/// The task must not be NULL. It is modified in-place, and becomes immutable.
|
||||||
|
///
|
||||||
|
/// The replica passed to `tc_task_to_mut` may be used freely after this call.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C void tc_task_to_immut(struct TCTask *task);
|
||||||
|
/// ```
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn tc_task_to_immut(task: *mut TCTask) {
|
||||||
|
// SAFETY:
|
||||||
|
// - task is not null (promised by caller)
|
||||||
|
// - task outlives 'a (promised by caller)
|
||||||
|
let tctask: &mut TCTask = unsafe { TCTask::from_ptr_arg_ref_mut(task) };
|
||||||
|
tctask.to_immut();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1005)]
|
||||||
/// Get the latest error for a task, or a string NULL ptr field if the last operation succeeded.
|
/// Get the latest error for a task, or a string NULL ptr field if the last operation succeeded.
|
||||||
/// Subsequent calls to this function will return NULL. The task pointer must not be NULL. The
|
/// Subsequent calls to this function will return NULL. The task pointer must not be NULL. The
|
||||||
/// caller must free the returned string.
|
/// caller must free the returned string.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C struct TCString tc_task_error(struct TCTask *task);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_error(task: *mut TCTask) -> TCString {
|
pub unsafe extern "C" fn tc_task_error(task: *mut TCTask) -> TCString {
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
|
@ -923,10 +1207,16 @@ pub unsafe extern "C" fn tc_task_error(task: *mut TCTask) -> TCString {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1006)]
|
||||||
/// Free a task. The given task must not be NULL. The task must not be used after this function
|
/// Free a task. The given task must not be NULL. The task must not be used after this function
|
||||||
/// returns, and must not be freed more than once.
|
/// returns, and must not be freed more than once.
|
||||||
///
|
///
|
||||||
/// If the task is currently mutable, it will first be made immutable.
|
/// If the task is currently mutable, it will first be made immutable.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C void tc_task_free(struct TCTask *task);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_free(task: *mut TCTask) {
|
pub unsafe extern "C" fn tc_task_free(task: *mut TCTask) {
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
|
@ -940,6 +1230,8 @@ pub unsafe extern "C" fn tc_task_free(task: *mut TCTask) {
|
||||||
drop(tctask);
|
drop(tctask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1011)]
|
||||||
/// Take an item from a TCTaskList. After this call, the indexed item is no longer associated
|
/// Take an item from a TCTaskList. After this call, the indexed item is no longer associated
|
||||||
/// with the list and becomes the caller's responsibility, just as if it had been returned from
|
/// with the list and becomes the caller's responsibility, just as if it had been returned from
|
||||||
/// `tc_replica_get_task`.
|
/// `tc_replica_get_task`.
|
||||||
|
@ -949,6 +1241,10 @@ pub unsafe extern "C" fn tc_task_free(task: *mut TCTask) {
|
||||||
/// index is out of bounds, this function will also return NULL.
|
/// index is out of bounds, this function will also return NULL.
|
||||||
///
|
///
|
||||||
/// The passed TCTaskList remains owned by the caller.
|
/// The passed TCTaskList remains owned by the caller.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C struct TCTask *tc_task_list_take(struct TCTaskList *tasks, size_t index);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_list_take(tasks: *mut TCTaskList, index: usize) -> *mut TCTask {
|
pub unsafe extern "C" fn tc_task_list_take(tasks: *mut TCTaskList, index: usize) -> *mut TCTask {
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
|
@ -962,10 +1258,16 @@ pub unsafe extern "C" fn tc_task_list_take(tasks: *mut TCTaskList, index: usize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1011)]
|
||||||
/// Free a TCTaskList instance. The instance, and all TCTaskList it contains, must not be used after
|
/// Free a TCTaskList instance. The instance, and all TCTaskList it contains, must not be used after
|
||||||
/// this call.
|
/// this call.
|
||||||
///
|
///
|
||||||
/// When this call returns, the `items` pointer will be NULL, signalling an invalid TCTaskList.
|
/// When this call returns, the `items` pointer will be NULL, signalling an invalid TCTaskList.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C void tc_task_list_free(struct TCTaskList *tasks);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_list_free(tasks: *mut TCTaskList) {
|
pub unsafe extern "C" fn tc_task_list_free(tasks: *mut TCTaskList) {
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
|
@ -984,7 +1286,7 @@ mod test {
|
||||||
let tasks = unsafe { TCTaskList::return_val(Vec::new()) };
|
let tasks = unsafe { TCTaskList::return_val(Vec::new()) };
|
||||||
assert!(!tasks.items.is_null());
|
assert!(!tasks.items.is_null());
|
||||||
assert_eq!(tasks.len, 0);
|
assert_eq!(tasks.len, 0);
|
||||||
assert_eq!(tasks._capacity, 0);
|
assert_eq!(tasks.capacity, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -994,6 +1296,6 @@ mod test {
|
||||||
unsafe { tc_task_list_free(&mut tasks) };
|
unsafe { tc_task_list_free(&mut tasks) };
|
||||||
assert!(tasks.items.is_null());
|
assert!(tasks.items.is_null());
|
||||||
assert_eq!(tasks.len, 0);
|
assert_eq!(tasks.len, 0);
|
||||||
assert_eq!(tasks._capacity, 0);
|
assert_eq!(tasks.capacity, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,22 @@
|
||||||
use crate::traits::*;
|
use crate::traits::*;
|
||||||
use crate::types::*;
|
use crate::types::*;
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 500)]
|
||||||
|
/// ***** TCUda *****
|
||||||
|
///
|
||||||
/// TCUda contains the details of a UDA.
|
/// TCUda contains the details of a UDA.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// typedef struct TCUda {
|
||||||
|
/// // Namespace of the UDA. For legacy UDAs, this may have a NULL ptr field.
|
||||||
|
/// struct TCString ns;
|
||||||
|
/// // UDA key. Must not be NULL.
|
||||||
|
/// struct TCString key;
|
||||||
|
/// // Content of the UDA. Must not be NULL.
|
||||||
|
/// struct TCString value;
|
||||||
|
/// } TCUda;
|
||||||
|
/// ```
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct TCUda {
|
pub struct TCUda {
|
||||||
|
@ -59,9 +74,25 @@ impl PassByValue for TCUda {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 510)]
|
||||||
|
/// ***** TCUdaList *****
|
||||||
|
///
|
||||||
/// TCUdaList represents a list of UDAs.
|
/// TCUdaList represents a list of UDAs.
|
||||||
///
|
///
|
||||||
/// The content of this struct must be treated as read-only.
|
/// The content of this struct must be treated as read-only.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// typedef struct TCUdaList {
|
||||||
|
/// // number of UDAs in items
|
||||||
|
/// size_t len;
|
||||||
|
/// // reserved
|
||||||
|
/// size_t _u1;
|
||||||
|
/// // Array of UDAs. These remain owned by the TCUdaList instance and will be freed by
|
||||||
|
/// // tc_uda_list_free. This pointer is never NULL for a valid TCUdaList.
|
||||||
|
/// struct TCUda *items;
|
||||||
|
/// } TCUdaList;
|
||||||
|
/// ```
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct TCUdaList {
|
pub struct TCUdaList {
|
||||||
/// number of UDAs in items
|
/// number of UDAs in items
|
||||||
|
@ -70,7 +101,7 @@ pub struct TCUdaList {
|
||||||
/// total size of items (internal use only)
|
/// total size of items (internal use only)
|
||||||
_capacity: libc::size_t,
|
_capacity: libc::size_t,
|
||||||
|
|
||||||
/// array of UDAs. These remain owned by the TCUdaList instance and will be freed by
|
/// Array of UDAs. These remain owned by the TCUdaList instance and will be freed by
|
||||||
/// tc_uda_list_free. This pointer is never NULL for a valid TCUdaList.
|
/// tc_uda_list_free. This pointer is never NULL for a valid TCUdaList.
|
||||||
items: *mut TCUda,
|
items: *mut TCUda,
|
||||||
}
|
}
|
||||||
|
@ -100,8 +131,14 @@ impl CList for TCUdaList {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 501)]
|
||||||
/// Free a TCUda instance. The instance, and the TCStrings it contains, must not be used
|
/// Free a TCUda instance. The instance, and the TCStrings it contains, must not be used
|
||||||
/// after this call.
|
/// after this call.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C void tc_uda_free(struct TCUda *tcuda);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_uda_free(tcuda: *mut TCUda) {
|
pub unsafe extern "C" fn tc_uda_free(tcuda: *mut TCUda) {
|
||||||
debug_assert!(!tcuda.is_null());
|
debug_assert!(!tcuda.is_null());
|
||||||
|
@ -111,10 +148,16 @@ pub unsafe extern "C" fn tc_uda_free(tcuda: *mut TCUda) {
|
||||||
drop(uda);
|
drop(uda);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 511)]
|
||||||
/// Free a TCUdaList instance. The instance, and all TCUdas it contains, must not be used after
|
/// Free a TCUdaList instance. The instance, and all TCUdas it contains, must not be used after
|
||||||
/// this call.
|
/// this call.
|
||||||
///
|
///
|
||||||
/// When this call returns, the `items` pointer will be NULL, signalling an invalid TCUdaList.
|
/// When this call returns, the `items` pointer will be NULL, signalling an invalid TCUdaList.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C void tc_uda_list_free(struct TCUdaList *tcudas);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_uda_list_free(tcudas: *mut TCUdaList) {
|
pub unsafe extern "C" fn tc_uda_list_free(tcudas: *mut TCUdaList) {
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
|
|
|
@ -3,14 +3,18 @@ use crate::types::*;
|
||||||
use libc;
|
use libc;
|
||||||
use taskchampion::Uuid;
|
use taskchampion::Uuid;
|
||||||
|
|
||||||
// NOTE: this must be a simple constant so that cbindgen can evaluate it
|
#[ffizz_header::item]
|
||||||
/// Length, in bytes, of the string representation of a UUID (without NUL terminator)
|
#[ffizz(order = 300)]
|
||||||
pub const TC_UUID_STRING_BYTES: usize = 36;
|
/// ***** TCUuid *****
|
||||||
|
///
|
||||||
/// TCUuid is used as a task identifier. Uuids do not contain any pointers and need not be freed.
|
/// TCUuid is used as a task identifier. Uuids do not contain any pointers and need not be freed.
|
||||||
/// Uuids are typically treated as opaque, but the bytes are available in big-endian format.
|
/// Uuids are typically treated as opaque, but the bytes are available in big-endian format.
|
||||||
///
|
///
|
||||||
/// cbindgen:field-names=[bytes]
|
/// ```c
|
||||||
|
/// typedef struct TCUuid {
|
||||||
|
/// uint8_t bytes[16];
|
||||||
|
/// } TCUuid;
|
||||||
|
/// ```
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct TCUuid([u8; 16]);
|
pub struct TCUuid([u8; 16]);
|
||||||
|
|
||||||
|
@ -28,35 +32,41 @@ impl PassByValue for TCUuid {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new, randomly-generated UUID.
|
#[ffizz_header::item]
|
||||||
#[no_mangle]
|
#[ffizz(order = 301)]
|
||||||
pub unsafe extern "C" fn tc_uuid_new_v4() -> TCUuid {
|
/// Length, in bytes, of the string representation of a UUID (without NUL terminator)
|
||||||
// SAFETY:
|
///
|
||||||
// - value is not allocated
|
/// ```c
|
||||||
unsafe { TCUuid::return_val(Uuid::new_v4()) }
|
/// #define TC_UUID_STRING_BYTES 36
|
||||||
}
|
/// ```
|
||||||
|
// TODO: debug_assert or static_assert this somewhere?
|
||||||
/// Create a new UUID with the nil value.
|
pub const TC_UUID_STRING_BYTES: usize = 36;
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn tc_uuid_nil() -> TCUuid {
|
|
||||||
// SAFETY:
|
|
||||||
// - value is not allocated
|
|
||||||
unsafe { TCUuid::return_val(Uuid::nil()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 310)]
|
||||||
/// TCUuidList represents a list of uuids.
|
/// TCUuidList represents a list of uuids.
|
||||||
///
|
///
|
||||||
/// The content of this struct must be treated as read-only.
|
/// The content of this struct must be treated as read-only.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// typedef struct TCUuidList {
|
||||||
|
/// // number of uuids in items
|
||||||
|
/// size_t len;
|
||||||
|
/// // reserved
|
||||||
|
/// size_t _u1;
|
||||||
|
/// // Array of uuids. This pointer is never NULL for a valid TCUuidList.
|
||||||
|
/// struct TCUuid *items;
|
||||||
|
/// } TCUuidList;
|
||||||
|
/// ```
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct TCUuidList {
|
pub struct TCUuidList {
|
||||||
/// number of uuids in items
|
/// number of uuids in items
|
||||||
len: libc::size_t,
|
len: libc::size_t,
|
||||||
|
|
||||||
/// total size of items (internal use only)
|
/// total size of items (internal use only)
|
||||||
_capacity: libc::size_t,
|
capacity: libc::size_t,
|
||||||
|
|
||||||
/// array of uuids. these remain owned by the TCUuidList instance and will be freed by
|
/// Array of uuids. This pointer is never NULL for a valid TCUuidList.
|
||||||
/// tc_uuid_list_free. This pointer is never NULL for a valid TCUuidList.
|
|
||||||
items: *mut TCUuid,
|
items: *mut TCUuid,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +76,7 @@ impl CList for TCUuidList {
|
||||||
unsafe fn from_raw_parts(items: *mut Self::Element, len: usize, cap: usize) -> Self {
|
unsafe fn from_raw_parts(items: *mut Self::Element, len: usize, cap: usize) -> Self {
|
||||||
TCUuidList {
|
TCUuidList {
|
||||||
len,
|
len,
|
||||||
_capacity: cap,
|
capacity: cap,
|
||||||
items,
|
items,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,12 +91,46 @@ impl CList for TCUuidList {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn into_raw_parts(self) -> (*mut Self::Element, usize, usize) {
|
fn into_raw_parts(self) -> (*mut Self::Element, usize, usize) {
|
||||||
(self.items, self.len, self._capacity)
|
(self.items, self.len, self.capacity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 302)]
|
||||||
|
/// Create a new, randomly-generated UUID.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C struct TCUuid tc_uuid_new_v4(void);
|
||||||
|
/// ```
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn tc_uuid_new_v4() -> TCUuid {
|
||||||
|
// SAFETY:
|
||||||
|
// - value is not allocated
|
||||||
|
unsafe { TCUuid::return_val(Uuid::new_v4()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 302)]
|
||||||
|
/// Create a new UUID with the nil value.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C struct TCUuid tc_uuid_nil(void);
|
||||||
|
/// ```
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn tc_uuid_nil() -> TCUuid {
|
||||||
|
// SAFETY:
|
||||||
|
// - value is not allocated
|
||||||
|
unsafe { TCUuid::return_val(Uuid::nil()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 302)]
|
||||||
/// Write the string representation of a TCUuid into the given buffer, which must be
|
/// Write the string representation of a TCUuid into the given buffer, which must be
|
||||||
/// at least TC_UUID_STRING_BYTES long. No NUL terminator is added.
|
/// at least TC_UUID_STRING_BYTES long. No NUL terminator is added.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C void tc_uuid_to_buf(struct TCUuid tcuuid, char *buf);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_uuid_to_buf(tcuuid: TCUuid, buf: *mut libc::c_char) {
|
pub unsafe extern "C" fn tc_uuid_to_buf(tcuuid: TCUuid, buf: *mut libc::c_char) {
|
||||||
debug_assert!(!buf.is_null());
|
debug_assert!(!buf.is_null());
|
||||||
|
@ -104,8 +148,14 @@ pub unsafe extern "C" fn tc_uuid_to_buf(tcuuid: TCUuid, buf: *mut libc::c_char)
|
||||||
uuid.as_hyphenated().encode_lower(buf);
|
uuid.as_hyphenated().encode_lower(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 302)]
|
||||||
/// Return the hyphenated string representation of a TCUuid. The returned string
|
/// Return the hyphenated string representation of a TCUuid. The returned string
|
||||||
/// must be freed with tc_string_free.
|
/// must be freed with tc_string_free.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C struct TCString tc_uuid_to_str(struct TCUuid tcuuid);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_uuid_to_str(tcuuid: TCUuid) -> TCString {
|
pub unsafe extern "C" fn tc_uuid_to_str(tcuuid: TCUuid) -> TCString {
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
|
@ -117,8 +167,14 @@ pub unsafe extern "C" fn tc_uuid_to_str(tcuuid: TCUuid) -> TCString {
|
||||||
unsafe { TCString::return_val(s.into()) }
|
unsafe { TCString::return_val(s.into()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 302)]
|
||||||
/// Parse the given string as a UUID. Returns TC_RESULT_ERROR on parse failure or if the given
|
/// Parse the given string as a UUID. Returns TC_RESULT_ERROR on parse failure or if the given
|
||||||
/// string is not valid.
|
/// string is not valid.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C TCResult tc_uuid_from_str(struct TCString s, struct TCUuid *uuid_out);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_uuid_from_str(s: TCString, uuid_out: *mut TCUuid) -> TCResult {
|
pub unsafe extern "C" fn tc_uuid_from_str(s: TCString, uuid_out: *mut TCUuid) -> TCResult {
|
||||||
debug_assert!(!s.is_null());
|
debug_assert!(!s.is_null());
|
||||||
|
@ -139,10 +195,16 @@ pub unsafe extern "C" fn tc_uuid_from_str(s: TCString, uuid_out: *mut TCUuid) ->
|
||||||
TCResult::Error
|
TCResult::Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 312)]
|
||||||
/// Free a TCUuidList instance. The instance, and all TCUuids it contains, must not be used after
|
/// Free a TCUuidList instance. The instance, and all TCUuids it contains, must not be used after
|
||||||
/// this call.
|
/// this call.
|
||||||
///
|
///
|
||||||
/// When this call returns, the `items` pointer will be NULL, signalling an invalid TCUuidList.
|
/// When this call returns, the `items` pointer will be NULL, signalling an invalid TCUuidList.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C void tc_uuid_list_free(struct TCUuidList *tcuuids);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_uuid_list_free(tcuuids: *mut TCUuidList) {
|
pub unsafe extern "C" fn tc_uuid_list_free(tcuuids: *mut TCUuidList) {
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
|
@ -161,7 +223,7 @@ mod test {
|
||||||
let tcuuids = unsafe { TCUuidList::return_val(Vec::new()) };
|
let tcuuids = unsafe { TCUuidList::return_val(Vec::new()) };
|
||||||
assert!(!tcuuids.items.is_null());
|
assert!(!tcuuids.items.is_null());
|
||||||
assert_eq!(tcuuids.len, 0);
|
assert_eq!(tcuuids.len, 0);
|
||||||
assert_eq!(tcuuids._capacity, 0);
|
assert_eq!(tcuuids.capacity, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -171,6 +233,6 @@ mod test {
|
||||||
unsafe { tc_uuid_list_free(&mut tcuuids) };
|
unsafe { tc_uuid_list_free(&mut tcuuids) };
|
||||||
assert!(tcuuids.items.is_null());
|
assert!(tcuuids.items.is_null());
|
||||||
assert_eq!(tcuuids.len, 0);
|
assert_eq!(tcuuids.len, 0);
|
||||||
assert_eq!(tcuuids._capacity, 0);
|
assert_eq!(tcuuids.capacity, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,10 @@ use crate::traits::*;
|
||||||
use crate::types::*;
|
use crate::types::*;
|
||||||
use taskchampion::{Uuid, WorkingSet};
|
use taskchampion::{Uuid, WorkingSet};
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1100)]
|
||||||
|
/// ***** TCWorkingSet *****
|
||||||
|
///
|
||||||
/// A TCWorkingSet represents a snapshot of the working set for a replica. It is not automatically
|
/// A TCWorkingSet represents a snapshot of the working set for a replica. It is not automatically
|
||||||
/// updated based on changes in the replica. Its lifetime is independent of the replica and it can
|
/// updated based on changes in the replica. Its lifetime is independent of the replica and it can
|
||||||
/// be freed at any time.
|
/// be freed at any time.
|
||||||
|
@ -23,6 +27,10 @@ use taskchampion::{Uuid, WorkingSet};
|
||||||
/// Once passed to `tc_replica_free`, a `*TCWorkingSet` becomes invalid and must not be used again.
|
/// Once passed to `tc_replica_free`, a `*TCWorkingSet` becomes invalid and must not be used again.
|
||||||
///
|
///
|
||||||
/// TCWorkingSet is not threadsafe.
|
/// TCWorkingSet is not threadsafe.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// typedef struct TCWorkingSet TCWorkingSet;
|
||||||
|
/// ```
|
||||||
pub struct TCWorkingSet(WorkingSet);
|
pub struct TCWorkingSet(WorkingSet);
|
||||||
|
|
||||||
impl PassByPointer for TCWorkingSet {}
|
impl PassByPointer for TCWorkingSet {}
|
||||||
|
@ -45,20 +53,38 @@ where
|
||||||
f(&tcws.0)
|
f(&tcws.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1101)]
|
||||||
/// Get the working set's length, or the number of UUIDs it contains.
|
/// Get the working set's length, or the number of UUIDs it contains.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C size_t tc_working_set_len(struct TCWorkingSet *ws);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_working_set_len(ws: *mut TCWorkingSet) -> usize {
|
pub unsafe extern "C" fn tc_working_set_len(ws: *mut TCWorkingSet) -> usize {
|
||||||
wrap(ws, |ws| ws.len())
|
wrap(ws, |ws| ws.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1101)]
|
||||||
/// Get the working set's largest index.
|
/// Get the working set's largest index.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C size_t tc_working_set_largest_index(struct TCWorkingSet *ws);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_working_set_largest_index(ws: *mut TCWorkingSet) -> usize {
|
pub unsafe extern "C" fn tc_working_set_largest_index(ws: *mut TCWorkingSet) -> usize {
|
||||||
wrap(ws, |ws| ws.largest_index())
|
wrap(ws, |ws| ws.largest_index())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1101)]
|
||||||
/// Get the UUID for the task at the given index. Returns true if the UUID exists in the working
|
/// Get the UUID for the task at the given index. Returns true if the UUID exists in the working
|
||||||
/// set. If not, returns false and does not change uuid_out.
|
/// set. If not, returns false and does not change uuid_out.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C bool tc_working_set_by_index(struct TCWorkingSet *ws, size_t index, struct TCUuid *uuid_out);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_working_set_by_index(
|
pub unsafe extern "C" fn tc_working_set_by_index(
|
||||||
ws: *mut TCWorkingSet,
|
ws: *mut TCWorkingSet,
|
||||||
|
@ -79,8 +105,14 @@ pub unsafe extern "C" fn tc_working_set_by_index(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1101)]
|
||||||
/// Get the working set index for the task with the given UUID. Returns 0 if the task is not in
|
/// Get the working set index for the task with the given UUID. Returns 0 if the task is not in
|
||||||
/// the working set.
|
/// the working set.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C size_t tc_working_set_by_uuid(struct TCWorkingSet *ws, struct TCUuid uuid);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_working_set_by_uuid(ws: *mut TCWorkingSet, uuid: TCUuid) -> usize {
|
pub unsafe extern "C" fn tc_working_set_by_uuid(ws: *mut TCWorkingSet, uuid: TCUuid) -> usize {
|
||||||
wrap(ws, |ws| {
|
wrap(ws, |ws| {
|
||||||
|
@ -91,8 +123,14 @@ pub unsafe extern "C" fn tc_working_set_by_uuid(ws: *mut TCWorkingSet, uuid: TCU
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ffizz_header::item]
|
||||||
|
#[ffizz(order = 1102)]
|
||||||
/// Free a TCWorkingSet. The given value must not be NULL. The value must not be used after this
|
/// Free a TCWorkingSet. The given value must not be NULL. The value must not be used after this
|
||||||
/// function returns, and must not be freed more than once.
|
/// function returns, and must not be freed more than once.
|
||||||
|
///
|
||||||
|
/// ```c
|
||||||
|
/// EXTERN_C void tc_working_set_free(struct TCWorkingSet *ws);
|
||||||
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_working_set_free(ws: *mut TCWorkingSet) {
|
pub unsafe extern "C" fn tc_working_set_free(ws: *mut TCWorkingSet) {
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -5,4 +5,4 @@ edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
cbindgen = "0.24.3"
|
taskchampion-lib = { path = "../lib" }
|
||||||
|
|
|
@ -3,8 +3,9 @@
|
||||||
//! At the moment it is very simple, but if this grows more subcommands then
|
//! At the moment it is very simple, but if this grows more subcommands then
|
||||||
//! it will be sensible to use `clap` or another similar library.
|
//! it will be sensible to use `clap` or another similar library.
|
||||||
|
|
||||||
use cbindgen::*;
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Write;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
pub fn main() -> anyhow::Result<()> {
|
pub fn main() -> anyhow::Result<()> {
|
||||||
|
@ -18,32 +19,13 @@ pub fn main() -> anyhow::Result<()> {
|
||||||
|
|
||||||
/// `cargo xtask codegen`
|
/// `cargo xtask codegen`
|
||||||
///
|
///
|
||||||
/// This uses cbindgen to generate `lib/taskchampion.h`.
|
/// This uses ffizz-header to generate `lib/taskchampion.h`.
|
||||||
fn codegen() -> anyhow::Result<()> {
|
fn codegen() -> anyhow::Result<()> {
|
||||||
let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
|
let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
|
||||||
let workspace_dir = manifest_dir.parent().unwrap();
|
let workspace_dir = manifest_dir.parent().unwrap();
|
||||||
let lib_crate_dir = workspace_dir.join("lib");
|
let lib_crate_dir = workspace_dir.join("lib");
|
||||||
|
let mut file = File::create(lib_crate_dir.join("taskchampion.h")).unwrap();
|
||||||
Builder::new()
|
write!(&mut file, "{}", ::taskchampion_lib::generate_header()).unwrap();
|
||||||
.with_crate(&lib_crate_dir)
|
|
||||||
.with_config(Config {
|
|
||||||
header: Some(include_str!("../../lib/header-intro.h").into()),
|
|
||||||
language: Language::C,
|
|
||||||
include_guard: Some("TASKCHAMPION_H".into()),
|
|
||||||
cpp_compat: true,
|
|
||||||
sys_includes: vec!["stdbool.h".into(), "stdint.h".into(), "time.h".into()],
|
|
||||||
usize_is_size_t: true,
|
|
||||||
no_includes: true,
|
|
||||||
enumeration: EnumConfig {
|
|
||||||
// this appears to still default to true for C
|
|
||||||
enum_class: false,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
..Default::default()
|
|
||||||
})
|
|
||||||
.generate()
|
|
||||||
.expect("Unable to generate bindings")
|
|
||||||
.write_to_file(lib_crate_dir.join("taskchampion.h"));
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue