frontend-utils: Move bookmark writer from desktop
This commit is contained in:
parent
54dcec7c60
commit
2cd915046e
|
@ -6,10 +6,10 @@ pub mod storage;
|
|||
use crate::cli::Opt;
|
||||
use crate::log::FilenamePattern;
|
||||
use crate::preferences::read::read_preferences;
|
||||
use crate::preferences::write::{BookmarksWriter, PreferencesWriter};
|
||||
use crate::preferences::write::PreferencesWriter;
|
||||
use anyhow::{Context, Error};
|
||||
use ruffle_core::backend::ui::US_ENGLISH;
|
||||
use ruffle_frontend_utils::bookmarks::{read_bookmarks, Bookmarks};
|
||||
use ruffle_frontend_utils::bookmarks::{read_bookmarks, Bookmarks, BookmarksWriter};
|
||||
use ruffle_frontend_utils::parse::DocumentHolder;
|
||||
use ruffle_render_wgpu::clap::{GraphicsBackend, PowerPreference};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
use crate::log::FilenamePattern;
|
||||
use crate::preferences::storage::StorageBackend;
|
||||
use crate::preferences::SavedGlobalPreferences;
|
||||
use ruffle_frontend_utils::bookmarks::{Bookmark, Bookmarks};
|
||||
use ruffle_frontend_utils::parse::DocumentHolder;
|
||||
use ruffle_frontend_utils::write::TableExt;
|
||||
use ruffle_render_wgpu::clap::{GraphicsBackend, PowerPreference};
|
||||
use toml_edit::{value, ArrayOfTables, Table};
|
||||
use toml_edit::value;
|
||||
use unic_langid::LanguageIdentifier;
|
||||
|
||||
pub struct PreferencesWriter<'a>(&'a mut DocumentHolder<SavedGlobalPreferences>);
|
||||
|
@ -76,293 +74,128 @@ impl<'a> PreferencesWriter<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct BookmarksWriter<'a>(&'a mut DocumentHolder<Bookmarks>);
|
||||
|
||||
impl<'a> BookmarksWriter<'a> {
|
||||
pub(super) fn new(bookmarks: &'a mut DocumentHolder<Bookmarks>) -> Self {
|
||||
Self(bookmarks)
|
||||
}
|
||||
|
||||
fn with_underlying_table(&mut self, fun: impl FnOnce(&mut Bookmarks, &mut ArrayOfTables)) {
|
||||
self.0.edit(|values, toml_document| {
|
||||
let table = toml_document.get_or_create_array_of_tables("bookmark");
|
||||
fun(values, table)
|
||||
})
|
||||
}
|
||||
|
||||
fn with_bookmark_table(&mut self, index: usize, fun: impl FnOnce(&mut Bookmarks, &mut Table)) {
|
||||
self.with_underlying_table(|values, array_of_tables| {
|
||||
let table = array_of_tables
|
||||
.get_mut(index)
|
||||
.expect("invalid bookmark index");
|
||||
fun(values, table)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn add(&mut self, bookmark: Bookmark) {
|
||||
self.with_underlying_table(|values, table| {
|
||||
let mut bookmark_table = Table::new();
|
||||
bookmark_table["url"] = value(bookmark.url.to_string());
|
||||
bookmark_table["name"] = value(&bookmark.name);
|
||||
table.push(bookmark_table);
|
||||
values.push(bookmark);
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_url(&mut self, index: usize, url: url::Url) {
|
||||
self.with_bookmark_table(index, |values, table| {
|
||||
table["url"] = value(url.as_str());
|
||||
values[index].url = url;
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_name(&mut self, index: usize, name: String) {
|
||||
self.with_bookmark_table(index, |values, table| {
|
||||
table["name"] = value(&name);
|
||||
values[index].name = name;
|
||||
})
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, index: usize) {
|
||||
self.with_underlying_table(|values, table| {
|
||||
table.remove(index);
|
||||
values.remove(index);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::preferences::read::read_preferences;
|
||||
use fluent_templates::loader::langid;
|
||||
use std::ops::Deref;
|
||||
|
||||
macro_rules! define_serialization_test_helpers {
|
||||
($read_method:ident, $doc_struct:ty, $writer:ident) => {
|
||||
fn check_roundtrip(preferences: &DocumentHolder<$doc_struct>) {
|
||||
let read_result = $read_method(&preferences.serialize());
|
||||
assert_eq!(
|
||||
preferences.deref(),
|
||||
read_result.values(),
|
||||
"roundtrip failed: expected != actual"
|
||||
);
|
||||
}
|
||||
ruffle_frontend_utils::define_serialization_test_helpers!(
|
||||
read_preferences,
|
||||
SavedGlobalPreferences,
|
||||
PreferencesWriter
|
||||
);
|
||||
|
||||
fn test(original: &str, fun: impl FnOnce(&mut $writer), expected: &str) {
|
||||
let mut preferences = $read_method(original).result;
|
||||
let mut writer = $writer::new(&mut preferences);
|
||||
fun(&mut writer);
|
||||
check_roundtrip(&preferences);
|
||||
assert_eq!(expected, preferences.serialize());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
mod preferences {
|
||||
use super::*;
|
||||
use crate::preferences::read::read_preferences;
|
||||
|
||||
define_serialization_test_helpers!(
|
||||
read_preferences,
|
||||
SavedGlobalPreferences,
|
||||
PreferencesWriter
|
||||
#[test]
|
||||
fn set_graphics_backend() {
|
||||
test(
|
||||
"",
|
||||
|writer| writer.set_graphics_backend(GraphicsBackend::Default),
|
||||
"graphics_backend = \"default\"\n",
|
||||
);
|
||||
|
||||
#[test]
|
||||
fn set_graphics_backend() {
|
||||
test(
|
||||
"",
|
||||
|writer| writer.set_graphics_backend(GraphicsBackend::Default),
|
||||
"graphics_backend = \"default\"\n",
|
||||
);
|
||||
|
||||
test(
|
||||
"graphics_backend = \"fast\"",
|
||||
|writer| writer.set_graphics_backend(GraphicsBackend::Vulkan),
|
||||
"graphics_backend = \"vulkan\"\n",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_graphics_power_preference() {
|
||||
test(
|
||||
"",
|
||||
|writer| writer.set_graphics_power_preference(PowerPreference::High),
|
||||
"graphics_power_preference = \"high\"\n",
|
||||
);
|
||||
|
||||
test(
|
||||
"graphics_power_preference = \"fast\"",
|
||||
|writer| writer.set_graphics_power_preference(PowerPreference::Low),
|
||||
"graphics_power_preference = \"low\"\n",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_language() {
|
||||
test(
|
||||
"",
|
||||
|writer| writer.set_language(langid!("en-US")),
|
||||
"language = \"en-US\"\n",
|
||||
);
|
||||
|
||||
test(
|
||||
"language = \"???\"",
|
||||
|writer| writer.set_language(langid!("en-Latn-US-valencia")),
|
||||
"language = \"en-Latn-US-valencia\"\n",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_output_device() {
|
||||
test(
|
||||
"",
|
||||
|writer| writer.set_output_device(Some("Speakers".to_string())),
|
||||
"output_device = \"Speakers\"\n",
|
||||
);
|
||||
|
||||
test(
|
||||
"output_device = \"Speakers\"",
|
||||
|writer| writer.set_output_device(None),
|
||||
"",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_volume() {
|
||||
test("", |writer| writer.set_volume(0.5), "volume = 0.5\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_mute() {
|
||||
test("", |writer| writer.set_mute(true), "mute = true\n");
|
||||
test(
|
||||
"mute = true",
|
||||
|writer| writer.set_mute(false),
|
||||
"mute = false\n",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_log_filename_pattern() {
|
||||
test(
|
||||
"",
|
||||
|writer| writer.set_log_filename_pattern(FilenamePattern::WithTimestamp),
|
||||
"log = { filename_pattern = \"with_timestamp\" }\n",
|
||||
);
|
||||
test(
|
||||
"log = { filename_pattern = \"with_timestamp\" }\n",
|
||||
|writer| writer.set_log_filename_pattern(FilenamePattern::SingleFile),
|
||||
"log = { filename_pattern = \"single_file\" }\n",
|
||||
);
|
||||
test(
|
||||
"[log]\nfilename_pattern = \"with_timestamp\"\n",
|
||||
|writer| writer.set_log_filename_pattern(FilenamePattern::SingleFile),
|
||||
"[log]\nfilename_pattern = \"single_file\"\n",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_storage_backend() {
|
||||
test(
|
||||
"",
|
||||
|writer| writer.set_storage_backend(StorageBackend::Disk),
|
||||
"storage = { backend = \"disk\" }\n",
|
||||
);
|
||||
test(
|
||||
"storage = { backend = \"disk\" }\n",
|
||||
|writer| writer.set_storage_backend(StorageBackend::Memory),
|
||||
"storage = { backend = \"memory\" }\n",
|
||||
);
|
||||
test(
|
||||
"[storage]\nbackend = \"disk\"\n",
|
||||
|writer| writer.set_storage_backend(StorageBackend::Memory),
|
||||
"[storage]\nbackend = \"memory\"\n",
|
||||
);
|
||||
}
|
||||
test(
|
||||
"graphics_backend = \"fast\"",
|
||||
|writer| writer.set_graphics_backend(GraphicsBackend::Vulkan),
|
||||
"graphics_backend = \"vulkan\"\n",
|
||||
);
|
||||
}
|
||||
|
||||
#[allow(clippy::unwrap_used)]
|
||||
mod bookmarks {
|
||||
use super::*;
|
||||
use ruffle_frontend_utils::bookmarks::read_bookmarks;
|
||||
use std::str::FromStr;
|
||||
use url::Url;
|
||||
|
||||
define_serialization_test_helpers!(read_bookmarks, Bookmarks, BookmarksWriter);
|
||||
|
||||
#[test]
|
||||
fn add_bookmark() {
|
||||
test(
|
||||
"",
|
||||
|writer| {
|
||||
writer.add(Bookmark {
|
||||
url: Url::from_str("file:///home/user/example.swf").unwrap(),
|
||||
name: "example.swf".to_string(),
|
||||
})
|
||||
},
|
||||
"[[bookmark]]\nurl = \"file:///home/user/example.swf\"\nname = \"example.swf\"\n",
|
||||
);
|
||||
test("[[bookmark]]\nurl = \"file:///home/user/example.swf\"\n", |writer| writer.add(Bookmark {
|
||||
url: Url::from_str("file:///home/user/another_file.swf").unwrap(),
|
||||
name: "another_file.swf".to_string(),
|
||||
}), "[[bookmark]]\nurl = \"file:///home/user/example.swf\"\n\n[[bookmark]]\nurl = \"file:///home/user/another_file.swf\"\nname = \"another_file.swf\"\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn modify_bookmark() {
|
||||
test(
|
||||
"[[bookmark]]\nurl = \"file:///example.swf\"\n",
|
||||
|writer| writer.set_name(0, "Custom Name".to_string()),
|
||||
"[[bookmark]]\nurl = \"file:///example.swf\"\nname = \"Custom Name\"\n",
|
||||
);
|
||||
test(
|
||||
"[[bookmark]]\nurl = \"file:///example.swf\"\nname = \"example.swf\"",
|
||||
|writer| writer.set_url(0, Url::parse("https://ruffle.rs/logo-anim.swf").unwrap()),
|
||||
"[[bookmark]]\nurl = \"https://ruffle.rs/logo-anim.swf\"\nname = \"example.swf\"\n",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn remove_bookmark() {
|
||||
test(
|
||||
"[[bookmark]]\nurl = \"file://home/user/example.swf\"\n\n[[bookmark]]\nurl = \"https://ruffle.rs/logo-anim.swf\"\n\n[[bookmark]]\nurl = \"file:///another_file.swf\"\n",
|
||||
|writer| {
|
||||
writer.remove(1);
|
||||
},
|
||||
"[[bookmark]]\nurl = \"file://home/user/example.swf\"\n\n[[bookmark]]\nurl = \"file:///another_file.swf\"\n",
|
||||
#[test]
|
||||
fn set_graphics_power_preference() {
|
||||
test(
|
||||
"",
|
||||
|writer| writer.set_graphics_power_preference(PowerPreference::High),
|
||||
"graphics_power_preference = \"high\"\n",
|
||||
);
|
||||
test("[[bookmark]]\nurl = \"file://home/user/example.swf\"\n\n[[bookmark]]\n\n[[bookmark]]\nurl = \"https://ruffle.rs/logo-anim.swf\"\n\n[[bookmark]]\nurl = \"invalid\"\n", |writer| {
|
||||
writer.remove(2);
|
||||
}, "[[bookmark]]\nurl = \"file://home/user/example.swf\"\n\n[[bookmark]]\n\n[[bookmark]]\nurl = \"invalid\"\n");
|
||||
|
||||
// check if we can remove invalid entries.
|
||||
test("[[bookmark]]", |writer| writer.remove(0), "");
|
||||
}
|
||||
test(
|
||||
"graphics_power_preference = \"fast\"",
|
||||
|writer| writer.set_graphics_power_preference(PowerPreference::Low),
|
||||
"graphics_power_preference = \"low\"\n",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn overwrite_invalid_bookmark_type() {
|
||||
test(
|
||||
"[bookmark]",
|
||||
|writer| {
|
||||
writer.add(Bookmark {
|
||||
url: Url::from_str("file:///test.swf").unwrap(),
|
||||
name: "test.swf".to_string(),
|
||||
})
|
||||
},
|
||||
"[[bookmark]]\nurl = \"file:///test.swf\"\nname = \"test.swf\"\n",
|
||||
);
|
||||
#[test]
|
||||
fn set_language() {
|
||||
test(
|
||||
"",
|
||||
|writer| writer.set_language(langid!("en-US")),
|
||||
"language = \"en-US\"\n",
|
||||
);
|
||||
|
||||
test(
|
||||
"bookmark = 1010",
|
||||
|writer| {
|
||||
writer.add(Bookmark {
|
||||
url: Url::from_str("file:///test.swf").unwrap(),
|
||||
name: "test.swf".to_string(),
|
||||
})
|
||||
},
|
||||
"[[bookmark]]\nurl = \"file:///test.swf\"\nname = \"test.swf\"\n",
|
||||
);
|
||||
}
|
||||
test(
|
||||
"language = \"???\"",
|
||||
|writer| writer.set_language(langid!("en-Latn-US-valencia")),
|
||||
"language = \"en-Latn-US-valencia\"\n",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_output_device() {
|
||||
test(
|
||||
"",
|
||||
|writer| writer.set_output_device(Some("Speakers".to_string())),
|
||||
"output_device = \"Speakers\"\n",
|
||||
);
|
||||
|
||||
test(
|
||||
"output_device = \"Speakers\"",
|
||||
|writer| writer.set_output_device(None),
|
||||
"",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_volume() {
|
||||
test("", |writer| writer.set_volume(0.5), "volume = 0.5\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_mute() {
|
||||
test("", |writer| writer.set_mute(true), "mute = true\n");
|
||||
test(
|
||||
"mute = true",
|
||||
|writer| writer.set_mute(false),
|
||||
"mute = false\n",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_log_filename_pattern() {
|
||||
test(
|
||||
"",
|
||||
|writer| writer.set_log_filename_pattern(FilenamePattern::WithTimestamp),
|
||||
"log = { filename_pattern = \"with_timestamp\" }\n",
|
||||
);
|
||||
test(
|
||||
"log = { filename_pattern = \"with_timestamp\" }\n",
|
||||
|writer| writer.set_log_filename_pattern(FilenamePattern::SingleFile),
|
||||
"log = { filename_pattern = \"single_file\" }\n",
|
||||
);
|
||||
test(
|
||||
"[log]\nfilename_pattern = \"with_timestamp\"\n",
|
||||
|writer| writer.set_log_filename_pattern(FilenamePattern::SingleFile),
|
||||
"[log]\nfilename_pattern = \"single_file\"\n",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_storage_backend() {
|
||||
test(
|
||||
"",
|
||||
|writer| writer.set_storage_backend(StorageBackend::Disk),
|
||||
"storage = { backend = \"disk\" }\n",
|
||||
);
|
||||
test(
|
||||
"storage = { backend = \"disk\" }\n",
|
||||
|writer| writer.set_storage_backend(StorageBackend::Memory),
|
||||
"storage = { backend = \"memory\" }\n",
|
||||
);
|
||||
test(
|
||||
"[storage]\nbackend = \"disk\"\n",
|
||||
|writer| writer.set_storage_backend(StorageBackend::Memory),
|
||||
"[storage]\nbackend = \"memory\"\n",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
mod read;
|
||||
mod write;
|
||||
pub use read::read_bookmarks;
|
||||
pub use write::BookmarksWriter;
|
||||
|
||||
use url::Url;
|
||||
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
use crate::bookmarks::{Bookmark, Bookmarks};
|
||||
use crate::parse::DocumentHolder;
|
||||
use crate::write::TableExt;
|
||||
use toml_edit::{value, ArrayOfTables, Table};
|
||||
|
||||
pub struct BookmarksWriter<'a>(&'a mut DocumentHolder<Bookmarks>);
|
||||
|
||||
impl<'a> BookmarksWriter<'a> {
|
||||
pub fn new(bookmarks: &'a mut DocumentHolder<Bookmarks>) -> Self {
|
||||
Self(bookmarks)
|
||||
}
|
||||
|
||||
fn with_underlying_table(&mut self, fun: impl FnOnce(&mut Bookmarks, &mut ArrayOfTables)) {
|
||||
self.0.edit(|values, toml_document| {
|
||||
let table = toml_document.get_or_create_array_of_tables("bookmark");
|
||||
fun(values, table)
|
||||
})
|
||||
}
|
||||
|
||||
fn with_bookmark_table(&mut self, index: usize, fun: impl FnOnce(&mut Bookmarks, &mut Table)) {
|
||||
self.with_underlying_table(|values, array_of_tables| {
|
||||
let table = array_of_tables
|
||||
.get_mut(index)
|
||||
.expect("invalid bookmark index");
|
||||
fun(values, table)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn add(&mut self, bookmark: Bookmark) {
|
||||
self.with_underlying_table(|values, table| {
|
||||
let mut bookmark_table = Table::new();
|
||||
bookmark_table["url"] = value(bookmark.url.to_string());
|
||||
bookmark_table["name"] = value(&bookmark.name);
|
||||
table.push(bookmark_table);
|
||||
values.push(bookmark);
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_url(&mut self, index: usize, url: url::Url) {
|
||||
self.with_bookmark_table(index, |values, table| {
|
||||
table["url"] = value(url.as_str());
|
||||
values[index].url = url;
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_name(&mut self, index: usize, name: String) {
|
||||
self.with_bookmark_table(index, |values, table| {
|
||||
table["name"] = value(&name);
|
||||
values[index].name = name;
|
||||
})
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, index: usize) {
|
||||
self.with_underlying_table(|values, table| {
|
||||
table.remove(index);
|
||||
values.remove(index);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::bookmarks::read_bookmarks;
|
||||
use url::Url;
|
||||
|
||||
crate::define_serialization_test_helpers!(read_bookmarks, Bookmarks, BookmarksWriter);
|
||||
|
||||
#[test]
|
||||
fn add_bookmark() {
|
||||
test(
|
||||
"",
|
||||
|writer| {
|
||||
writer.add(Bookmark {
|
||||
url: Url::parse("file:///home/user/example.swf").unwrap(),
|
||||
name: "example.swf".to_string(),
|
||||
})
|
||||
},
|
||||
"[[bookmark]]\nurl = \"file:///home/user/example.swf\"\nname = \"example.swf\"\n",
|
||||
);
|
||||
test("[[bookmark]]\nurl = \"file:///home/user/example.swf\"\n", |writer| writer.add(Bookmark {
|
||||
url: Url::parse("file:///home/user/another_file.swf").unwrap(),
|
||||
name: "another_file.swf".to_string(),
|
||||
}), "[[bookmark]]\nurl = \"file:///home/user/example.swf\"\n\n[[bookmark]]\nurl = \"file:///home/user/another_file.swf\"\nname = \"another_file.swf\"\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn modify_bookmark() {
|
||||
test(
|
||||
"[[bookmark]]\nurl = \"file:///example.swf\"\n",
|
||||
|writer| writer.set_name(0, "Custom Name".to_string()),
|
||||
"[[bookmark]]\nurl = \"file:///example.swf\"\nname = \"Custom Name\"\n",
|
||||
);
|
||||
test(
|
||||
"[[bookmark]]\nurl = \"file:///example.swf\"\nname = \"example.swf\"",
|
||||
|writer| writer.set_url(0, Url::parse("https://ruffle.rs/logo-anim.swf").unwrap()),
|
||||
"[[bookmark]]\nurl = \"https://ruffle.rs/logo-anim.swf\"\nname = \"example.swf\"\n",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn remove_bookmark() {
|
||||
test(
|
||||
"[[bookmark]]\nurl = \"file://home/user/example.swf\"\n\n[[bookmark]]\nurl = \"https://ruffle.rs/logo-anim.swf\"\n\n[[bookmark]]\nurl = \"file:///another_file.swf\"\n",
|
||||
|writer| {
|
||||
writer.remove(1);
|
||||
},
|
||||
"[[bookmark]]\nurl = \"file://home/user/example.swf\"\n\n[[bookmark]]\nurl = \"file:///another_file.swf\"\n",
|
||||
);
|
||||
test("[[bookmark]]\nurl = \"file://home/user/example.swf\"\n\n[[bookmark]]\n\n[[bookmark]]\nurl = \"https://ruffle.rs/logo-anim.swf\"\n\n[[bookmark]]\nurl = \"invalid\"\n", |writer| {
|
||||
writer.remove(2);
|
||||
}, "[[bookmark]]\nurl = \"file://home/user/example.swf\"\n\n[[bookmark]]\n\n[[bookmark]]\nurl = \"invalid\"\n");
|
||||
|
||||
// check if we can remove invalid entries.
|
||||
test("[[bookmark]]", |writer| writer.remove(0), "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn overwrite_invalid_bookmark_type() {
|
||||
test(
|
||||
"[bookmark]",
|
||||
|writer| {
|
||||
writer.add(Bookmark {
|
||||
url: Url::parse("file:///test.swf").unwrap(),
|
||||
name: "test.swf".to_string(),
|
||||
})
|
||||
},
|
||||
"[[bookmark]]\nurl = \"file:///test.swf\"\nname = \"test.swf\"\n",
|
||||
);
|
||||
|
||||
test(
|
||||
"bookmark = 1010",
|
||||
|writer| {
|
||||
writer.add(Bookmark {
|
||||
url: Url::parse("file:///test.swf").unwrap(),
|
||||
name: "test.swf".to_string(),
|
||||
})
|
||||
},
|
||||
"[[bookmark]]\nurl = \"file:///test.swf\"\nname = \"test.swf\"\n",
|
||||
);
|
||||
}
|
||||
}
|
|
@ -20,3 +20,26 @@ impl TableExt for Table {
|
|||
.expect("type was just created")
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! define_serialization_test_helpers {
|
||||
($read_method:ident, $doc_struct:ty, $writer:ident) => {
|
||||
fn check_roundtrip(preferences: &DocumentHolder<$doc_struct>) {
|
||||
use std::ops::Deref;
|
||||
let read_result = $read_method(&preferences.serialize());
|
||||
assert_eq!(
|
||||
preferences.deref(),
|
||||
read_result.values(),
|
||||
"roundtrip failed: expected != actual"
|
||||
);
|
||||
}
|
||||
|
||||
fn test(original: &str, fun: impl FnOnce(&mut $writer), expected: &str) {
|
||||
let mut preferences = $read_method(original).result;
|
||||
let mut writer = $writer::new(&mut preferences);
|
||||
fun(&mut writer);
|
||||
check_roundtrip(&preferences);
|
||||
assert_eq!(expected, preferences.serialize());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue