From a90a5cba08fdf6c0ceb95101c275108a152a3aed Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 12 Jun 2024 07:35:37 +0200 Subject: Merging upstream version 127.0. Signed-off-by: Daniel Baumann --- .../components/uniffi-fixtures/todolist/src/lib.rs | 150 +++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 toolkit/components/uniffi-fixtures/todolist/src/lib.rs (limited to 'toolkit/components/uniffi-fixtures/todolist/src/lib.rs') diff --git a/toolkit/components/uniffi-fixtures/todolist/src/lib.rs b/toolkit/components/uniffi-fixtures/todolist/src/lib.rs new file mode 100644 index 0000000000..11cdc63aee --- /dev/null +++ b/toolkit/components/uniffi-fixtures/todolist/src/lib.rs @@ -0,0 +1,150 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use std::sync::{Arc, RwLock}; + +use once_cell::sync::Lazy; + +#[derive(Debug, Clone)] +pub struct TodoEntry { + text: String, +} + +// There is a single "default" TodoList that can be shared +// by all consumers of this component. Depending on requirements, +// a real app might like to use a `Weak<>` rather than an `Arc<>` +// here to reduce the risk of circular references. +static DEFAULT_LIST: Lazy>>> = Lazy::new(|| RwLock::new(None)); + +#[derive(Debug, thiserror::Error)] +pub enum TodoError { + #[error("The todo does not exist!")] + TodoDoesNotExist, + #[error("The todolist is empty!")] + EmptyTodoList, + #[error("That todo already exists!")] + DuplicateTodo, + #[error("Empty String error!: {0}")] + EmptyString(String), + #[error("I am a delegated Error: {0}")] + DeligatedError(#[from] std::io::Error), +} + +/// Get a reference to the global default TodoList, if set. +/// +fn get_default_list() -> Option> { + DEFAULT_LIST.read().unwrap().clone() +} + +/// Set the global default TodoList. +/// +/// This will silently drop any previously set value. +/// +fn set_default_list(list: Arc) { + *DEFAULT_LIST.write().unwrap() = Some(list); +} + +/// Create a new TodoEntry from the given string. +/// +fn create_entry_with>(item: S) -> Result { + let text = item.into(); + if text.is_empty() { + return Err(TodoError::EmptyString( + "Cannot add empty string as entry".to_string(), + )); + } + Ok(TodoEntry { text }) +} + +type Result = std::result::Result; + +// A simple Todolist. +// UniFFI requires that we use interior mutability for managing mutable state, so we wrap our `Vec` in a RwLock. +// (A Mutex would also work, but a RwLock is more appropriate for this use-case, so we use it). +#[derive(Debug)] +pub struct TodoList { + items: RwLock>, +} + +impl TodoList { + fn new() -> Self { + Self { + items: RwLock::new(Vec::new()), + } + } + + fn add_item>(&self, item: S) -> Result<()> { + let item = item.into(); + if item.is_empty() { + return Err(TodoError::EmptyString( + "Cannot add empty string as item".to_string(), + )); + } + let mut items = self.items.write().unwrap(); + if items.contains(&item) { + return Err(TodoError::DuplicateTodo); + } + items.push(item); + Ok(()) + } + + fn get_last(&self) -> Result { + let items = self.items.read().unwrap(); + items.last().cloned().ok_or(TodoError::EmptyTodoList) + } + + fn get_first(&self) -> Result { + let items = self.items.read().unwrap(); + items.first().cloned().ok_or(TodoError::EmptyTodoList) + } + + fn add_entries(&self, entries: Vec) { + let mut items = self.items.write().unwrap(); + items.extend(entries.into_iter().map(|e| e.text)) + } + + fn add_entry(&self, entry: TodoEntry) -> Result<()> { + self.add_item(entry.text) + } + + fn add_items>(&self, items: Vec) { + let mut my_items = self.items.write().unwrap(); + my_items.extend(items.into_iter().map(Into::into)) + } + + fn get_items(&self) -> Vec { + let items = self.items.read().unwrap(); + items.clone() + } + + fn get_entries(&self) -> Vec { + let items = self.items.read().unwrap(); + items + .iter() + .map(|text| TodoEntry { text: text.clone() }) + .collect() + } + + fn get_last_entry(&self) -> Result { + let text = self.get_last()?; + Ok(TodoEntry { text }) + } + + fn clear_item>(&self, item: S) -> Result<()> { + let item = item.into(); + let mut items = self.items.write().unwrap(); + let idx = items + .iter() + .position(|s| s == &item) + .ok_or(TodoError::TodoDoesNotExist)?; + items.remove(idx); + Ok(()) + } + + fn make_default(self: Arc) { + set_default_list(self); + } +} + +uniffi::include_scaffolding!("todolist"); -- cgit v1.2.3