From 3aa373d83a5266a6f5d7d65c482db6d054400cd9 Mon Sep 17 00:00:00 2001 From: Jackson Coxson Date: Mon, 24 Mar 2025 18:21:23 -0600 Subject: [PATCH] Add libplist conversion --- Cargo.lock | 313 +++++++++++++++++++++++++++++++++--- ffi/Cargo.toml | 2 + ffi/build.rs | 1 + ffi/examples/CMakeLists.txt | 27 +++- ffi/src/util.rs | 9 ++ 5 files changed, 328 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ba67b5f..f11f850 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,6 +26,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + [[package]] name = "anstream" version = "0.6.18" @@ -111,12 +120,32 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + [[package]] name = "autocfg" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "autotools" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef941527c41b0fc0dd48511a8154cd5fc7e29200a0ff8b7203c5d777dbc795cf" +dependencies = [ + "cc", +] + [[package]] name = "backtrace" version = "0.3.74" @@ -138,6 +167,35 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "bindgen" +version = "0.59.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bd2a9a458e8f4304c52c43ebb0cfbd520289f8379a52e329a38afda99bf8eb8" +dependencies = [ + "bitflags 1.3.2", + "cexpr", + "clang-sys", + "clap 2.34.0", + "env_logger 0.9.3", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "which", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitflags" version = "2.8.0" @@ -230,7 +288,7 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eadd868a2ce9ca38de7eeafdcec9c7065ef89b42b32f0839278d55f35c54d1ff" dependencies = [ - "clap", + "clap 4.5.27", "heck 0.4.1", "indexmap", "log", @@ -252,6 +310,15 @@ dependencies = [ "shlex", ] +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -270,6 +337,32 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "ansi_term", + "atty", + "bitflags 1.3.2", + "strsim 0.8.0", + "textwrap", + "unicode-width", + "vec_map", +] + [[package]] name = "clap" version = "4.5.27" @@ -289,7 +382,7 @@ dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim", + "strsim 0.11.1", ] [[package]] @@ -443,6 +536,12 @@ dependencies = [ "litrs", ] +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + [[package]] name = "encoding_rs" version = "0.8.35" @@ -462,6 +561,19 @@ dependencies = [ "regex", ] +[[package]] +name = "env_logger" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + [[package]] name = "env_logger" version = "0.11.7" @@ -673,7 +785,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ba121d81ab5ea05b0cd5858516266800bf965531a794f7ac58e3eeb804f364f" dependencies = [ - "bitflags", + "bitflags 2.8.0", "libc", "windows-sys 0.59.0", ] @@ -707,6 +819,12 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +[[package]] +name = "glob" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" + [[package]] name = "h2" version = "0.4.7" @@ -744,6 +862,24 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "home" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" +dependencies = [ + "windows-sys 0.59.0", +] + [[package]] name = "http" version = "1.2.0" @@ -784,6 +920,12 @@ version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" +[[package]] +name = "humantime" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b112acc8b3adf4b107a8ec20977da0273a8c386765a3ec0229bd500a1443f9f" + [[package]] name = "hyper" version = "1.6.0" @@ -982,7 +1124,7 @@ dependencies = [ "base64", "byteorder", "bytes", - "env_logger", + "env_logger 0.11.7", "futures", "indexmap", "json", @@ -990,7 +1132,7 @@ dependencies = [ "ns-keyed-archive", "openssl", "plist", - "rand", + "rand 0.9.0", "reqwest", "serde", "serde_json", @@ -1012,6 +1154,8 @@ dependencies = [ "log", "once_cell", "openssl-sys", + "plist", + "plist_plus", "simplelog", "tokio", ] @@ -1020,8 +1164,8 @@ dependencies = [ name = "idevice-tools" version = "0.1.0" dependencies = [ - "clap", - "env_logger", + "clap 4.5.27", + "env_logger 0.11.7", "idevice", "log", "ns-keyed-archive", @@ -1122,6 +1266,18 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + [[package]] name = "libc" version = "0.2.171" @@ -1203,6 +1359,12 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.8.3" @@ -1246,7 +1408,7 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" dependencies = [ - "bitflags", + "bitflags 2.8.0", "cfg-if", "cfg_aliases 0.1.1", "libc", @@ -1259,12 +1421,22 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags", + "bitflags 2.8.0", "cfg-if", "cfg_aliases 0.2.1", "libc", ] +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "ns-keyed-archive" version = "0.1.3" @@ -1281,7 +1453,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f237a10fe003123daa55a74b63a0b0a65de1671b2d128711ffe5886891a8f77f" dependencies = [ - "clap", + "clap 4.5.27", "plist", "thiserror", ] @@ -1322,7 +1494,7 @@ version = "0.10.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f5e534d133a060a3c19daec1eb3e98ec6f4685978834f2dbadfe2ec215bab64e" dependencies = [ - "bitflags", + "bitflags 2.8.0", "cfg-if", "foreign-types", "libc", @@ -1399,6 +1571,12 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + [[package]] name = "percent-encoding" version = "2.3.1" @@ -1436,9 +1614,9 @@ checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "plist" -version = "1.7.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016" +checksum = "eac26e981c03a6e53e0aee43c113e3202f5581d5360dae7bd2c70e800dd0451d" dependencies = [ "base64", "indexmap", @@ -1447,6 +1625,20 @@ dependencies = [ "time", ] +[[package]] +name = "plist_plus" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167429a361cacecf5cab907c235e620b3faf5f36b97d7f72c32907ccdca700cf" +dependencies = [ + "autotools", + "bindgen", + "cc", + "libc", + "log", + "rand 0.8.5", +] + [[package]] name = "portable-atomic" version = "1.11.0" @@ -1504,17 +1696,38 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + [[package]] name = "rand" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" dependencies = [ - "rand_chacha", - "rand_core", + "rand_chacha 0.9.0", + "rand_core 0.9.3", "zerocopy", ] +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + [[package]] name = "rand_chacha" version = "0.9.0" @@ -1522,7 +1735,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.15", ] [[package]] @@ -1540,7 +1762,7 @@ version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ - "bitflags", + "bitflags 2.8.0", ] [[package]] @@ -1637,13 +1859,19 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustix" version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags", + "bitflags 2.8.0", "errno", "libc", "linux-raw-sys", @@ -1724,7 +1952,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags", + "bitflags 2.8.0", "core-foundation", "core-foundation-sys", "libc", @@ -1868,6 +2096,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + [[package]] name = "strsim" version = "0.11.1" @@ -1928,7 +2162,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags", + "bitflags 2.8.0", "core-foundation", "system-configuration-sys", ] @@ -1966,6 +2200,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + [[package]] name = "thiserror" version = "2.0.11" @@ -2194,7 +2437,7 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53141e64197ff7e758b8152615e50bb4a3b18c970738876e7906d31f242c7d6e" dependencies = [ - "bitflags", + "bitflags 2.8.0", "blocking", "byteorder", "bytes", @@ -2222,7 +2465,7 @@ version = "2.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "397f7515d2ab25d87dbb89af39b6813c1df6a89703003d7939c1f6bbc0fbeed9" dependencies = [ - "bitflags", + "bitflags 2.8.0", "blocking", "byteorder", "bytes", @@ -2256,6 +2499,12 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11cd88e12b17c6494200a9c1b683a04fcac9573ed74cd1b62aeb2727c5592243" +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + [[package]] name = "untrusted" version = "0.9.0" @@ -2348,6 +2597,12 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + [[package]] name = "version_check" version = "0.9.5" @@ -2468,6 +2723,18 @@ dependencies = [ "rustls-pki-types", ] +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + [[package]] name = "widestring" version = "1.2.0" @@ -2731,7 +2998,7 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" dependencies = [ - "bitflags", + "bitflags 2.8.0", ] [[package]] diff --git a/ffi/Cargo.toml b/ffi/Cargo.toml index 5efdeef..9e6c602 100644 --- a/ffi/Cargo.toml +++ b/ffi/Cargo.toml @@ -12,6 +12,8 @@ once_cell = "1.21.1" tokio = { version = "1.44.1", features = ["full"] } libc = "0.2.171" openssl-sys = { version = "0.9", features = ["vendored"] } +plist = "1.7.1" +plist_plus = { version = "0.2.6", features = ["vendored"] } [build-dependencies] cbindgen = "0.28.0" diff --git a/ffi/build.rs b/ffi/build.rs index efb8dc2..ad44920 100644 --- a/ffi/build.rs +++ b/ffi/build.rs @@ -12,6 +12,7 @@ fn main() { ) .with_language(cbindgen::Language::C) .with_sys_include("sys/socket.h") + .with_sys_include("plist/plist.h") .generate() .expect("Unable to generate bindings") .write_to_file("idevice.h"); diff --git a/ffi/examples/CMakeLists.txt b/ffi/examples/CMakeLists.txt index d9ea0ae..33c6b3b 100644 --- a/ffi/examples/CMakeLists.txt +++ b/ffi/examples/CMakeLists.txt @@ -6,7 +6,7 @@ project(IdeviceFFI C) # Set the paths set(HEADER_FILE ${CMAKE_SOURCE_DIR}/../idevice.h) -set(STATIC_LIB ${CMAKE_SOURCE_DIR}/target/release/libidevice_ffi.a) +set(STATIC_LIB ${CMAKE_SOURCE_DIR}/../../target/release/libidevice_ffi.a) set(EXAMPLES_DIR ${CMAKE_SOURCE_DIR}/../examples) # Find all C example files @@ -30,6 +30,31 @@ foreach(EXAMPLE_FILE ${EXAMPLE_SOURCES}) # Link OpenSSL target_link_libraries(${EXAMPLE_NAME} PRIVATE OpenSSL::SSL OpenSSL::Crypto) + # libplist + + if( APPLE ) + # use static linking + pkg_search_module(PLIST REQUIRED libplist-2.0) + find_library( LIBPLIST libplist-2.0.a REQUIRED ) + message( STATUS "(Static linking) LIBPLIST " ${LIBPLIST} ) + target_link_libraries ( ${EXAMPLE_NAME} PRIVATE ${LIBPLIST} ) + elseif( WIN32) + pkg_search_module(PLIST REQUIRED libplist-2.0) + find_library( LIBPLIST ${PLIST_LIBRARIES} PATH ${PLIST_LIBDIR} ) + target_link_libraries ( ${EXAMPLE_NAME} PRIVATE ${LIBPLIST} ) + else () + pkg_search_module(PLIST libplist>=2.0) + if(NOT PLIST_FOUND) + pkg_search_module(PLIST REQUIRED libplist-2.0) + endif() + find_library( LIBPLIST ${PLIST_LIBRARIES} PATH ${PLIST_LIBDIR} ) + target_link_libraries ( ${EXAMPLE_NAME} PUBLIC ${LIBPLIST} ) + endif() + if ( PLIST_FOUND ) + message( STATUS "found libplist-${PLIST_VERSION}" ) + endif() + target_include_directories( ${EXAMPLE_NAME} PRIVATE ${PLIST_INCLUDE_DIRS} ) + # Bulk-link common macOS system frameworks if(APPLE) target_link_libraries(${EXAMPLE_NAME} PRIVATE diff --git a/ffi/src/util.rs b/ffi/src/util.rs index cacabc7..19eacea 100644 --- a/ffi/src/util.rs +++ b/ffi/src/util.rs @@ -6,6 +6,7 @@ use std::{ }; use libc::{sockaddr_in, sockaddr_in6}; +use plist::Value; use crate::IdeviceErrorCode; @@ -75,3 +76,11 @@ pub(crate) fn c_addr_to_rust(addr: *const libc::sockaddr) -> Result plist_plus::Plist { + let buf = Vec::new(); + let mut writer = std::io::BufWriter::new(buf); + plist::to_writer_xml(&mut writer, v).unwrap(); + let buf = String::from_utf8(writer.into_inner().unwrap()).unwrap(); + plist_plus::Plist::from_xml(buf).unwrap() +}