rstudio / rstudioapi

Safely access RStudio's API (when available)
http://rstudio.github.io/rstudioapi
Other
165 stars 35 forks source link

Data does not round trip through `writePreference()` and `readPreference()` #248

Open gadenbuie opened 2 years ago

gadenbuie commented 2 years ago

Related to #247, I discovered that readPreference() does not preserve the structure of the value as it was provided to writePreference(). At a quick glance, the difference looks a lot like the data is being serialized as JSON but read with auto_unbox = FALSE.

Here's a small reprex list:

value_write <- list(
  fruit = "banana",
  drink = "coffee"
)

rstudioapi::writePreference("test", value_write)
value_read <- rstudioapi::readPreference("test", default = NULL)

waldo::compare(value_write, value_read)
#> `old$fruit` is a character vector ('banana')
#> `new$fruit` is a list
#> 
#> `old$drink` is a character vector ('coffee')
#> `new$drink` is a list

str(value_read)
#> List of 2
#>   $ fruit:List of 1
#>     ..$ : chr "banana"
#>   $ drink:List of 1
#>     ..$ : chr "coffee"

I thought I could handle serialization myself with jsonlite::serializeJSON(), but this led to #247.

value_write_json <- jsonlite::serializeJSON(value_write)
rstudioapi::writePreference("test", value_write_json)
#> Error in .rs.writePrefInternal("rs_writeApiPref", prefName, value) : 
#>   Type mismatch: expected <Object>; got <String>

I can safely roundtrip the data by serializing to a json string and storing in a named list, so I have a workaround, but it means a lot of boilerplate code to work around how the list is handled.

rstudioapi::writePreference("test", list(value = value_write_json))
# because of the first bit, we need $value[[1]] instead of just $value
value_read_json <- rstudioapi::readPreference("test", NULL)$value[[1]]
value_read_json <- jsonlite::unserializeJSON(value_read_json)

waldo::compare(value_write, value_read_json)
#> ✓ No differences
Session Info ``` > rstudioapi::versionInfo() $mode [1] "desktop" $version [1] ‘2022.6.0.25’ $long_version [1] "2022.06.0-daily+25" $release_name [1] "Spotted Wakerobin" ─ Session info ───────────────────────────────────────────────────────────────────── setting value version R version 3.6.3 (2020-02-29) os OS X Snow Leopard 11.6.2 system x86_64, darwin15.6.0 ui RStudio language (EN) collate en_US.UTF-8 ctype en_US.UTF-8 tz America/New_York date 2022-01-28 ─ Packages ───────────────────────────────────────────────────────────────────────── package * version date lib source jsonlite 1.7.3 2022-01-17 [1] CRAN (R 3.6.3) rstudioapi 0.13.0-9000 2022-01-28 [1] Github (rstudio/rstudioapi@5d0f087) ```