Janitor: Always use `#![no_std] for runtime lib

And call `extern crate std` when the feature is enabled.
I've read this is the good practice on how to do it.
So that the std prelude is no longer included automatically.
There is then less difference between std and and no-std build which
should avoid surprises in the CI when we use things from the prelude.

The downside is that there is a bit of churn in the tests
This commit is contained in:
Olivier Goffart 2025-01-27 18:02:37 +01:00
parent e24e9ffb60
commit c98d234b9e
47 changed files with 112 additions and 129 deletions

View file

@ -3,8 +3,10 @@
/*! This crate just expose the function used by the C++ integration */
#![cfg_attr(not(feature = "std"), no_std)]
#![no_std]
extern crate alloc;
#[cfg(feature = "std")]
extern crate std;
use alloc::rc::Rc;
use core::ffi::c_void;

View file

@ -2,7 +2,6 @@
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
use alloc::rc::Rc;
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, string::String};
use core::ffi::c_void;
use i_slint_core::api::{

View file

@ -30,6 +30,8 @@
"refcell",
"Rgba",
"rtti",
"Smol",
"smolstr",
"subspan",
"uninit",
"unmap",

View file

@ -3,11 +3,8 @@
// cSpell: ignore descendents
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use crate::{items::ItemRc, SharedString};
use alloc::vec::Vec;
use bitflags::bitflags;
/// The property names of the accessible-properties

View file

@ -4,7 +4,6 @@
#![warn(missing_docs)]
//! The animation system
#[cfg(not(feature = "std"))]
use alloc::boxed::Box;
use core::cell::Cell;
#[cfg(not(feature = "std"))]
@ -15,7 +14,6 @@ mod cubic_bezier {
//! (from lyon_algorithms 0.17)
type S = f32;
use euclid::default::Point2D as Point;
#[cfg(not(feature = "std"))]
#[allow(unused)]
use num_traits::Float;
trait Scalar {
@ -274,10 +272,7 @@ impl AnimationDriver {
}
}
#[cfg(all(not(feature = "std"), feature = "unsafe-single-threaded"))]
use crate::unsafe_single_threaded::thread_local;
thread_local!(
crate::thread_local!(
/// This is the default instance of the animation driver that's used to advance all property animations
/// at the same time.
pub static CURRENT_ANIMATION_DRIVER : AnimationDriver = AnimationDriver::default()

View file

@ -13,9 +13,7 @@ use crate::graphics::{Rgba8Pixel, SharedPixelBuffer};
use crate::input::{KeyEventType, MouseEvent};
use crate::item_tree::ItemTreeVTable;
use crate::window::{WindowAdapter, WindowInner};
#[cfg(not(feature = "std"))]
use alloc::boxed::Box;
#[cfg(not(feature = "std"))]
use alloc::string::String;
/// A position represented in the coordinate space of logical pixels. That is the space before applying

View file

@ -10,7 +10,6 @@ but then it should also be renamed everywhere, including in the language grammar
#![warn(missing_docs)]
#[cfg(not(feature = "std"))]
use alloc::boxed::Box;
use core::cell::Cell;

View file

@ -6,7 +6,6 @@
//! This module defines a `ComponentFactory` and related code.
use crate::api::ComponentHandle;
use crate::item_tree::{ItemTreeRc, ItemTreeVTable, ItemTreeWeak};
#[cfg(not(feature = "std"))]
use alloc::boxed::Box;
use alloc::rc::Rc;
use core::fmt::Debug;

View file

@ -3,14 +3,11 @@
use crate::api::PlatformError;
use crate::platform::{EventLoopProxy, Platform};
#[cfg(all(not(feature = "std"), feature = "unsafe-single-threaded"))]
use crate::thread_local;
use crate::Property;
#[cfg(not(feature = "std"))]
use alloc::boxed::Box;
use alloc::rc::Rc;
thread_local! {
crate::thread_local! {
pub(crate) static GLOBAL_CONTEXT : once_cell::unsync::OnceCell<SlintContext>
= const { once_cell::unsync::OnceCell::new() }
}

View file

@ -8,10 +8,8 @@
use crate::api::EventLoopError;
use crate::SlintContext;
#[cfg(not(feature = "std"))]
use alloc::boxed::Box;
use alloc::task::Wake;
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use core::future::Future;
use core::ops::DerefMut;

View file

@ -15,9 +15,7 @@ use crate::api::PlatformError;
use crate::lengths::LogicalLength;
use crate::Coord;
use crate::SharedString;
#[cfg(not(feature = "std"))]
use alloc::boxed::Box;
#[cfg(not(feature = "std"))]
use alloc::format;
pub use euclid;

View file

@ -421,7 +421,7 @@ impl ImageInner {
// Ignore error when rendering a 0x0 image, that's just an empty image
Err(resvg::usvg::Error::InvalidSize) => None,
Err(err) => {
eprintln!("Error rendering SVG: {err}");
std::eprintln!("Error rendering SVG: {err}");
None
}
},

View file

@ -42,7 +42,7 @@ pub(crate) struct ImageCache(
>,
);
thread_local!(pub(crate) static IMAGE_CACHE: core::cell::RefCell<ImageCache> =
crate::thread_local!(pub(crate) static IMAGE_CACHE: core::cell::RefCell<ImageCache> =
core::cell::RefCell::new(
ImageCache(
clru::CLruCache::with_config(
@ -87,7 +87,7 @@ impl ImageCache {
return Some(ImageInner::Svg(vtable::VRc::new(
super::svg::load_from_path(path, cache_key).map_or_else(
|err| {
eprintln!("Error loading SVG from {}: {}", &path, err);
crate::debug_log!("Error loading SVG from {}: {}", &path, err);
None
},
Some,
@ -97,7 +97,7 @@ impl ImageCache {
image::open(std::path::Path::new(&path.as_str())).map_or_else(
|decode_err| {
eprintln!("Error loading image from {}: {}", &path, decode_err);
crate::debug_log!("Error loading image from {}: {}", &path, decode_err);
None
},
|image| {
@ -122,7 +122,7 @@ impl ImageCache {
return Some(ImageInner::Svg(vtable::VRc::new(
super::svg::load_from_data(data.as_slice(), cache_key).map_or_else(
|svg_err| {
eprintln!("Error loading SVG: {}", svg_err);
crate::debug_log!("Error loading SVG: {}", svg_err);
None
},
Some,
@ -145,7 +145,7 @@ impl ImageCache {
buffer: dynamic_image_to_shared_image_buffer(image),
}),
Err(decode_err) => {
eprintln!("Error decoding embedded image: {}", decode_err);
crate::debug_log!("Error decoding embedded image: {}", decode_err);
None
}
}

View file

@ -53,7 +53,7 @@ impl HTMLImage {
}
}
pub fn source(&self) -> String {
pub fn source(&self) -> alloc::string::String {
self.dom_element.src()
}

View file

@ -5,6 +5,7 @@
This module contains path related types and functions for the run-time library.
*/
use crate::debug_log;
use crate::items::PathEvent;
#[cfg(feature = "rtti")]
use crate::rtti::*;
@ -304,7 +305,7 @@ impl PathData {
) {
Ok(()) => LyonPathIteratorVariant::FromPath(builder.build()),
Err(e) => {
eprintln!("Error while parsing path commands '{commands}': {e:?}");
debug_log!("Error while parsing path commands '{commands}': {e:?}");
LyonPathIteratorVariant::FromPath(Default::default())
}
}

View file

@ -10,9 +10,7 @@ use crate::debug_log;
use crate::timers::{Timer, TimerMode};
use alloc::format;
use alloc::rc::Rc;
#[cfg(not(feature = "std"))]
use alloc::string::String;
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use core::cell::RefCell;

View file

@ -15,7 +15,6 @@ use crate::timers::Timer;
use crate::window::{WindowAdapter, WindowInner};
use crate::{Coord, Property, SharedString};
use alloc::rc::Rc;
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use const_field_offset::FieldOffsets;
use core::cell::Cell;

View file

@ -62,6 +62,7 @@ pub fn default_previous_in_local_focus_chain(
#[cfg(test)]
mod tests {
use super::*;
use std::vec;
use crate::item_tree::ItemTreeNode;

View file

@ -16,7 +16,6 @@ use crate::lengths::{
use crate::properties::PropertyTracker;
use crate::window::WindowInner;
use crate::{Brush, Coord, SharedString};
#[cfg(not(feature = "std"))]
use alloc::boxed::Box;
use core::cell::{Cell, RefCell};
use core::pin::Pin;

View file

@ -1224,6 +1224,7 @@ pub(crate) mod ffi {
#[cfg(test)]
mod tests {
use super::*;
use std::vec;
struct TestItemTree {
parent_component: Option<ItemTreeRc>,

View file

@ -22,7 +22,6 @@ use crate::properties::{Property, PropertyTracker};
#[cfg(feature = "rtti")]
use crate::rtti::*;
use crate::window::WindowAdapter;
#[cfg(not(feature = "std"))]
use alloc::boxed::Box;
use alloc::rc::Rc;
use const_field_offset::FieldOffsets;

View file

@ -25,7 +25,6 @@ use crate::rtti::*;
use crate::window::WindowAdapter;
use crate::Callback;
use crate::Property;
#[cfg(not(feature = "std"))]
use alloc::boxed::Box;
use alloc::rc::Rc;
use const_field_offset::FieldOffsets;
@ -36,7 +35,6 @@ use core::time::Duration;
use euclid::num::Ceil;
use euclid::num::Zero;
use i_slint_core_macros::*;
#[cfg(not(feature = "std"))]
#[allow(unused)]
use num_traits::Float;

View file

@ -27,7 +27,6 @@ use crate::rtti::*;
use crate::window::{InputMethodProperties, InputMethodRequest, WindowAdapter, WindowInner};
use crate::{Callback, Coord, Property, SharedString, SharedVector};
use alloc::rc::Rc;
#[cfg(not(feature = "std"))]
use alloc::string::String;
use const_field_offset::FieldOffsets;
use core::cell::Cell;

View file

@ -6,8 +6,11 @@
#![doc = include_str!("README.md")]
#![doc(html_logo_url = "https://slint.dev/logo/slint-logo-square-light.svg")]
#![deny(unsafe_code)]
#![cfg_attr(not(feature = "std"), no_std)]
#![no_std]
extern crate alloc;
#[cfg(feature = "std")]
extern crate std;
#[cfg(all(not(feature = "std"), feature = "unsafe-single-threaded"))]
pub(crate) mod unsafe_single_threaded;
@ -17,6 +20,8 @@ compile_error!(
);
#[cfg(all(not(feature = "std"), feature = "unsafe-single-threaded"))]
use crate::unsafe_single_threaded::thread_local;
#[cfg(feature = "std")]
use std::thread_local;
pub mod accessibility;
pub mod animations;

View file

@ -141,7 +141,7 @@ pub trait Model {
/// internal [`ModelNotify`].
fn set_row_data(&self, _row: usize, _data: Self::Data) {
#[cfg(feature = "std")]
eprintln!(
crate::debug_log!(
"Model::set_row_data called on a model of type {} which does not re-implement this method. \
This happens when trying to modify a read-only model",
core::any::type_name::<Self>(),
@ -1284,6 +1284,7 @@ impl From<&str> for StandardListViewItem {
#[cfg(test)]
mod tests {
use super::*;
use std::vec;
#[test]
fn test_tracking_model_handle() {

View file

@ -232,7 +232,8 @@ where
#[test]
fn test_map_model() {
let wrapped_rc = Rc::new(VecModel::from(vec![1, 2, 3]));
use alloc::string::ToString;
let wrapped_rc = Rc::new(VecModel::from(std::vec![1, 2, 3]));
let map = MapModel::new(wrapped_rc.clone(), |x| x.to_string());
wrapped_rc.set_row_data(2, 42);
@ -494,7 +495,7 @@ where
#[test]
fn test_filter_model() {
let wrapped_rc = Rc::new(VecModel::from(vec![1, 2, 3, 4, 5, 6]));
let wrapped_rc = Rc::new(VecModel::from(std::vec![1, 2, 3, 4, 5, 6]));
let filter = Rc::new(FilterModel::new(wrapped_rc.clone(), |x| x % 2 == 0));
let _checker = ModelChecker::new(filter.clone());
@ -534,7 +535,7 @@ fn test_filter_model() {
#[test]
fn test_filter_model_source_model() {
let wrapped_rc = Rc::new(VecModel::from(vec![1, 2, 3, 4]));
let wrapped_rc = Rc::new(VecModel::from(std::vec![1, 2, 3, 4]));
let model = Rc::new(FilterModel::new(wrapped_rc.clone(), |x| x % 2 == 0));
let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
@ -932,10 +933,11 @@ where
#[cfg(test)]
mod sort_tests {
use super::*;
use std::vec;
#[test]
fn test_sorted_model_insert() {
let wrapped_rc = Rc::new(VecModel::from(vec![3, 4, 1, 2]));
let wrapped_rc = Rc::new(VecModel::from(std::vec![3, 4, 1, 2]));
let sorted_model = Rc::new(SortModel::new(wrapped_rc.clone(), |lhs, rhs| lhs.cmp(rhs)));
let _checker = ModelChecker::new(sorted_model.clone());
@ -1218,6 +1220,7 @@ where
#[cfg(test)]
mod reversed_tests {
use super::*;
use std::vec;
#[track_caller]
fn check_content(model: &ReverseModel<Rc<VecModel<i32>>>, expected: &[i32]) {
@ -1242,7 +1245,7 @@ mod reversed_tests {
#[test]
fn test_reversed_model_insert() {
for (idx, mapped_idx) in [(0, 4), (1, 3), (2, 2), (3, 1), (4, 0)] {
println!("Inserting at {} expecting mapped to {}", idx, mapped_idx);
std::println!("Inserting at {} expecting mapped to {}", idx, mapped_idx);
let wrapped_rc = Rc::new(VecModel::from(vec![1, 2, 3, 4]));
let model = Rc::new(ReverseModel::new(wrapped_rc.clone()));
let _checker = ModelChecker::new(model.clone());
@ -1268,7 +1271,7 @@ mod reversed_tests {
#[test]
fn test_reversed_model_remove() {
for (idx, mapped_idx) in [(0, 3), (1, 2), (2, 1), (3, 0)] {
println!("Removing at {} expecting mapped to {}", idx, mapped_idx);
std::println!("Removing at {} expecting mapped to {}", idx, mapped_idx);
let wrapped_rc = Rc::new(VecModel::from(vec![1, 2, 3, 4]));
let model = Rc::new(ReverseModel::new(wrapped_rc.clone()));
let _checker = ModelChecker::new(model.clone());
@ -1293,8 +1296,8 @@ mod reversed_tests {
#[test]
fn test_reversed_model_changed() {
for (idx, mapped_idx) in [(0, 3), (1, 2), (2, 1), (3, 0)] {
println!("Changing at {} expecting mapped to {}", idx, mapped_idx);
let wrapped_rc = Rc::new(VecModel::from(vec![1, 2, 3, 4]));
std::println!("Changing at {} expecting mapped to {}", idx, mapped_idx);
let wrapped_rc = Rc::new(VecModel::from(std::vec![1, 2, 3, 4]));
let model = Rc::new(ReverseModel::new(wrapped_rc.clone()));
let _checker = ModelChecker::new(model.clone());
@ -1318,7 +1321,7 @@ mod reversed_tests {
#[test]
fn test_reversed_model_source_model() {
let wrapped_rc = Rc::new(VecModel::from(vec![1, 2, 3, 4]));
let wrapped_rc = Rc::new(VecModel::from(std::vec![1, 2, 3, 4]));
let model = Rc::new(ReverseModel::new(wrapped_rc.clone()));
let _checker = ModelChecker::new(model.clone());
@ -1333,15 +1336,16 @@ mod reversed_tests {
#[test]
fn test_long_chain_integrity() {
use alloc::string::ToString;
let origin_model = Rc::new(VecModel::from((0..100).collect::<Vec<_>>()));
let checker1 = ModelChecker::new(origin_model.clone());
let fizzbuzz = Rc::new(MapModel::new(origin_model.clone(), |number| {
if (number % 3) == 0 && (number % 5) == 0 {
"FizzBuzz".to_owned()
"FizzBuzz".to_string()
} else if (number % 3) == 0 {
"Fizz".to_owned()
"Fizz".to_string()
} else if (number % 5) == 0 {
"Buzz".to_owned()
"Buzz".to_string()
} else {
number.to_string()
}

View file

@ -16,10 +16,8 @@ pub use crate::software_renderer;
use crate::unsafe_single_threaded::OnceCell;
pub use crate::window::{LayoutConstraints, WindowAdapter, WindowProperties};
use crate::SharedString;
#[cfg(not(feature = "std"))]
use alloc::boxed::Box;
use alloc::rc::Rc;
#[cfg(not(feature = "std"))]
use alloc::string::String;
#[cfg(all(feature = "std", not(target_os = "android")))]
use once_cell::sync::OnceCell;

View file

@ -16,7 +16,6 @@
/// A singled linked list whose nodes are pinned
mod single_linked_list_pin {
#![allow(unsafe_code)]
#[cfg(not(feature = "std"))]
use alloc::boxed::Box;
use core::pin::Pin;
@ -77,8 +76,8 @@ mod single_linked_list_pin {
head.push_front(2);
head.push_front(3);
assert_eq!(
head.iter().map(|x: Pin<&i32>| *x.get_ref()).collect::<Vec<i32>>(),
vec![3, 2, 1]
head.iter().map(|x: Pin<&i32>| *x.get_ref()).collect::<std::vec::Vec<i32>>(),
std::vec![3, 2, 1]
);
}
#[test]
@ -260,7 +259,6 @@ pub(crate) mod dependency_tracker {
type DependencyListHead = dependency_tracker::DependencyListHead<*const BindingHolder>;
type DependencyNode = dependency_tracker::DependencyNode<*const BindingHolder>;
#[cfg(not(feature = "std"))]
use alloc::boxed::Box;
use alloc::rc::Rc;
use core::cell::{Cell, RefCell, UnsafeCell};
@ -330,6 +328,8 @@ unsafe impl<F: Fn(*mut ()) -> BindingResult> BindingCallable for F {
}
}
#[cfg(feature = "std")]
use std::thread_local;
#[cfg(feature = "std")]
scoped_tls_hkt::scoped_thread_local!(static CURRENT_BINDING : for<'a> Option<Pin<&'a BindingHolder>>);

View file

@ -2,8 +2,6 @@
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
use super::{BindingHolder, BindingResult, BindingVTable, DependencyListHead};
#[cfg(all(not(feature = "std"), feature = "unsafe-single-threaded"))]
use crate::thread_local;
use alloc::boxed::Box;
use core::cell::Cell;
use core::marker::PhantomPinned;
@ -11,7 +9,7 @@ use core::pin::Pin;
use core::ptr::addr_of;
// TODO a pinned thread local key?
thread_local! {static CHANGED_NODES : Pin<Box<DependencyListHead>> = Box::pin(DependencyListHead::default()) }
crate::thread_local! {static CHANGED_NODES : Pin<Box<DependencyListHead>> = Box::pin(DependencyListHead::default()) }
struct ChangeTrackerInner<T, EvalFn, NotifyFn, Data> {
eval_fn: EvalFn,
@ -188,20 +186,20 @@ fn change_tracker() {
let change1 = ChangeTracker::default();
let change2 = ChangeTracker::default();
let state = Rc::new(core::cell::RefCell::new(String::new()));
let state = Rc::new(core::cell::RefCell::new(std::string::String::new()));
change1.init(
(state.clone(), prop1.clone()),
|(_, prop1)| prop1.as_ref().get(),
|(state, _), val| {
*state.borrow_mut() += &format!(":1({val})");
*state.borrow_mut() += &std::format!(":1({val})");
},
);
change2.init(
(state.clone(), prop2.clone()),
|(_, prop2)| prop2.as_ref().get(),
|(state, _), val| {
*state.borrow_mut() += &format!(":2({val})");
*state.borrow_mut() += &std::format!(":2({val})");
},
);

View file

@ -1,7 +1,6 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
#[cfg(not(feature = "std"))]
use alloc::boxed::Box;
use alloc::rc::Rc;
use core::pin::Pin;

View file

@ -10,8 +10,9 @@
pub type FieldOffset<T, U> = const_field_offset::FieldOffset<T, U, const_field_offset::AllowPin>;
use crate::items::PropertyAnimation;
use alloc::boxed::Box;
use alloc::rc::Rc;
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use core::convert::{TryFrom, TryInto};
use core::pin::Pin;

View file

@ -535,7 +535,7 @@ fn simple_test() {
assert_ne!(x, y);
let z: [i32; 3] = [1, 2, 3];
assert_eq!(z, x.as_slice());
let vec: Vec<i32> = vec![1, 2, 3];
let vec: std::vec::Vec<i32> = std::vec![1, 2, 3];
assert_eq!(x, vec);
let def: SharedVector<i32> = Default::default();
assert_eq!(def, SharedVector::<i32>::default());
@ -561,6 +561,7 @@ fn invalid_capacity_test() {
#[test]
fn collect_from_iter_with_no_size_hint() {
use std::string::{String, ToString};
struct NoSizeHintIter<'a> {
data: &'a [&'a str],
i: usize,
@ -604,7 +605,7 @@ fn test_capacity_grows_only_when_needed() {
#[test]
fn test_vector_clear() {
let mut vec: SharedVector<String> = Default::default();
let mut vec: SharedVector<std::string::String> = Default::default();
vec.clear();
vec.push("Hello".into());
vec.push("World".into());

View file

@ -34,7 +34,6 @@ use crate::textlayout::{AbstractFont, FontMetrics, TextParagraphLayout};
use crate::window::{WindowAdapter, WindowInner};
use crate::{Brush, Color, Coord, ImageInner, StaticTextures};
use alloc::rc::{Rc, Weak};
#[cfg(not(feature = "std"))]
use alloc::{vec, vec::Vec};
use core::cell::{Cell, RefCell};
use core::pin::Pin;
@ -811,7 +810,7 @@ impl RendererSealed for SoftwareRenderer {
fn register_font_from_memory(
&self,
data: &'static [u8],
) -> Result<(), Box<dyn std::error::Error>> {
) -> Result<(), std::boxed::Box<dyn std::error::Error>> {
self::fonts::systemfonts::register_font_from_memory(data)
}
@ -819,7 +818,7 @@ impl RendererSealed for SoftwareRenderer {
fn register_font_from_path(
&self,
path: &std::path::Path,
) -> Result<(), Box<dyn std::error::Error>> {
) -> Result<(), std::boxed::Box<dyn std::error::Error>> {
self::fonts::systemfonts::register_font_from_path(path)
}

View file

@ -2,13 +2,9 @@
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
use alloc::rc::Rc;
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use core::cell::RefCell;
#[cfg(all(not(feature = "std"), feature = "unsafe-single-threaded"))]
use crate::thread_local_ as thread_local;
use super::{Fixed, PhysicalLength, PhysicalSize};
use crate::graphics::{BitmapFont, FontRequest};
use crate::items::TextWrap;
@ -16,7 +12,7 @@ use crate::lengths::{LogicalLength, LogicalSize, ScaleFactor};
use crate::textlayout::{FontMetrics, TextLayout};
use crate::Coord;
thread_local! {
crate::thread_local! {
static BITMAP_FONTS: RefCell<Vec<&'static BitmapFont>> = RefCell::default()
}

View file

@ -3,6 +3,7 @@
use core::cell::RefCell;
use alloc::boxed::Box;
use alloc::rc::Rc;
use std::collections::HashMap;
@ -12,7 +13,7 @@ use i_slint_common::sharedfontdb::{self, fontdb};
use super::super::PhysicalLength;
use super::vectorfont::VectorFont;
thread_local! {
crate::thread_local! {
static FONTDUE_FONTS: RefCell<HashMap<fontdb::ID, Rc<fontdue::Font>>> = Default::default();
}
@ -86,7 +87,7 @@ pub fn register_font_from_memory(data: &'static [u8]) -> Result<(), Box<dyn std:
#[cfg(not(target_family = "wasm"))]
pub fn register_font_from_path(path: &std::path::Path) -> Result<(), Box<dyn std::error::Error>> {
let requested_path = path.canonicalize().unwrap_or_else(|_| path.to_owned());
let requested_path = path.canonicalize().unwrap_or_else(|_| path.into());
sharedfontdb::FONT_DB.with_borrow_mut(|fonts| {
for face_info in fonts.faces() {
match &face_info.source {

View file

@ -36,7 +36,7 @@ type GlyphCache = clru::CLruCache<
RenderableGlyphWeightScale,
>;
thread_local!(static GLYPH_CACHE: core::cell::RefCell<GlyphCache> =
crate::thread_local!(static GLYPH_CACHE: core::cell::RefCell<GlyphCache> =
core::cell::RefCell::new(
clru::CLruCache::with_config(
clru::CLruCacheConfig::new(core::num::NonZeroUsize::new(1 * 1024 * 1024).unwrap())

View file

@ -11,7 +11,6 @@ use crate::graphics::{PixelFormat, SharedImageBuffer};
use crate::lengths::{PointLengths as _, SizeLengths as _};
use crate::Color;
use alloc::rc::Rc;
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use euclid::Length;

View file

@ -7,7 +7,6 @@
#![warn(missing_docs)]
use crate::SharedVector;
#[cfg(not(feature = "std"))]
use alloc::string::String;
use core::fmt::{Debug, Display, Write};
use core::ops::Deref;
@ -318,6 +317,7 @@ pub fn shared_string_from_number(n: f64) -> SharedString {
#[test]
fn simple_test() {
use std::string::ToString;
let x = SharedString::from("hello world!");
assert_eq!(x, "hello world!");
assert_ne!(x, "hello world?");
@ -342,7 +342,7 @@ fn simple_test() {
fn threading() {
let shared_cst = SharedString::from("Hello there!");
let shared_mtx = std::sync::Arc::new(std::sync::Mutex::new(SharedString::from("Shared:")));
let mut handles = vec![];
let mut handles = std::vec![];
for _ in 0..20 {
let cst = shared_cst.clone();
let mtx = shared_mtx.clone();

View file

@ -102,6 +102,7 @@ pub fn default_debug_log(_arguments: core::fmt::Arguments) {
cfg_if::cfg_if! {
if #[cfg(target_arch = "wasm32")] {
use wasm_bindgen::prelude::*;
use std::string::ToString;
#[wasm_bindgen]
extern "C" {
@ -111,7 +112,7 @@ pub fn default_debug_log(_arguments: core::fmt::Arguments) {
log(&_arguments.to_string());
} else if #[cfg(feature = "std")] {
eprintln!("{}", _arguments);
std::eprintln!("{}", _arguments);
}
}
}

View file

@ -21,7 +21,6 @@
//! Emit current line as new line
//!
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use euclid::num::{One, Zero};
@ -461,7 +460,7 @@ fn test_elision() {
.map(|r| r.unwrap())
.collect::<Vec<char>>()
})
.collect::<String>();
.collect::<std::string::String>();
debug_assert_eq!(rendered_text, "This is a lo…")
}
@ -503,7 +502,7 @@ fn test_exact_fit() {
.map(|r| r.unwrap())
.collect::<Vec<char>>()
})
.collect::<String>();
.collect::<std::string::String>();
debug_assert_eq!(rendered_text, "Fits")
}
@ -548,10 +547,10 @@ fn test_no_line_separators_characters_rendered() {
.map(|r| r.unwrap())
.collect::<Vec<char>>()
})
.collect::<String>()
.collect::<std::string::String>()
})
.collect::<Vec<_>>();
debug_assert_eq!(rendered_text, vec!["Hello", "World"]);
debug_assert_eq!(rendered_text, std::vec!["Hello", "World"]);
}
#[test]
@ -638,7 +637,7 @@ fn byte_offset_for_empty_line() {
fn test_byte_offset() {
let font = FixedTestFont;
let text = "Hello World";
let mut end_helper_text = text.to_string();
let mut end_helper_text = std::string::String::from(text);
end_helper_text.push('!');
let paragraph = TextParagraphLayout {

View file

@ -119,6 +119,8 @@ impl<'a, Length: Clone + Default + core::ops::AddAssign + Zero + Copy> Iterator
#[cfg(test)]
use super::{FixedTestFont, TextLayout};
#[cfg(test)]
use std::{vec, vec::Vec};
#[test]
fn fragment_iterator_simple() {

View file

@ -207,7 +207,7 @@ fn test_empty_line_break() {
None,
TextWrap::WordWrap,
)
.collect::<Vec<_>>();
.collect::<std::vec::Vec<_>>();
assert_eq!(lines.len(), 1);
assert_eq!(lines[0].line_text(text), "");
}
@ -225,7 +225,7 @@ fn test_basic_line_break_char_wrap() {
None,
TextWrap::CharWrap,
)
.collect::<Vec<_>>();
.collect::<std::vec::Vec<_>>();
assert_eq!(lines.len(), 2);
assert_eq!(lines[0].line_text(text), "Hello Wo");
assert_eq!(lines[1].line_text(text), "rld");
@ -243,7 +243,7 @@ fn test_basic_line_break() {
None,
TextWrap::WordWrap,
)
.collect::<Vec<_>>();
.collect::<std::vec::Vec<_>>();
assert_eq!(lines.len(), 2);
assert_eq!(lines[0].line_text(text), "Hello");
assert_eq!(lines[1].line_text(text), "World");
@ -261,7 +261,7 @@ fn test_basic_line_break_max_lines() {
Some(1),
TextWrap::WordWrap,
)
.collect::<Vec<_>>();
.collect::<std::vec::Vec<_>>();
assert_eq!(lines.len(), 1);
assert_eq!(lines[0].line_text(text), "Hello");
}
@ -278,7 +278,7 @@ fn test_linebreak_trailing_space() {
None,
TextWrap::WordWrap,
)
.collect::<Vec<_>>();
.collect::<std::vec::Vec<_>>();
assert_eq!(lines.len(), 1);
assert_eq!(lines[0].line_text(text), "Hello");
}
@ -290,7 +290,7 @@ fn test_forced_break() {
let shape_buffer = ShapeBuffer::new(&TextLayout { font: &font, letter_spacing: None }, text);
let lines =
TextLineBreaker::<FixedTestFont>::new(text, &shape_buffer, None, None, TextWrap::WordWrap)
.collect::<Vec<_>>();
.collect::<std::vec::Vec<_>>();
assert_eq!(lines.len(), 2);
assert_eq!(lines[0].line_text(text), "Hello");
assert_eq!(lines[1].line_text(text), "World");
@ -303,7 +303,7 @@ fn test_forced_break_multi() {
let shape_buffer = ShapeBuffer::new(&TextLayout { font: &font, letter_spacing: None }, text);
let lines =
TextLineBreaker::<FixedTestFont>::new(text, &shape_buffer, None, None, TextWrap::WordWrap)
.collect::<Vec<_>>();
.collect::<std::vec::Vec<_>>();
assert_eq!(lines.len(), 4);
assert_eq!(lines[0].line_text(text), "Hello");
assert_eq!(lines[1].line_text(text), "");
@ -323,7 +323,7 @@ fn test_forced_break_multi_char_wrap() {
None,
TextWrap::CharWrap,
)
.collect::<Vec<_>>();
.collect::<std::vec::Vec<_>>();
assert_eq!(lines.len(), 6);
assert_eq!(lines[0].line_text(text), "Hel");
assert_eq!(lines[1].line_text(text), "lo");
@ -345,7 +345,7 @@ fn test_forced_break_max_lines() {
Some(2),
TextWrap::WordWrap,
)
.collect::<Vec<_>>();
.collect::<std::vec::Vec<_>>();
assert_eq!(lines.len(), 2);
assert_eq!(lines[0].line_text(text), "Hello");
assert_eq!(lines[1].line_text(text), "");
@ -363,7 +363,7 @@ fn test_nbsp_break() {
None,
TextWrap::WordWrap,
)
.collect::<Vec<_>>();
.collect::<std::vec::Vec<_>>();
assert_eq!(lines.len(), 2);
assert_eq!(lines[0].line_text(text), "Ok");
assert_eq!(lines[1].line_text(text), "Hello\u{00a0}World");
@ -376,7 +376,7 @@ fn test_single_line_multi_break_opportunity() {
let shape_buffer = ShapeBuffer::new(&TextLayout { font: &font, letter_spacing: None }, text);
let lines =
TextLineBreaker::<FixedTestFont>::new(text, &shape_buffer, None, None, TextWrap::WordWrap)
.collect::<Vec<_>>();
.collect::<std::vec::Vec<_>>();
assert_eq!(lines.len(), 1);
assert_eq!(lines[0].line_text(text), "a b c");
}
@ -393,7 +393,7 @@ fn test_basic_line_break_anywhere_fallback() {
None,
TextWrap::WordWrap,
)
.collect::<Vec<_>>();
.collect::<std::vec::Vec<_>>();
assert_eq!(lines.len(), 2);
assert_eq!(lines[0].line_text(text), "Hello");
assert_eq!(lines[1].line_text(text), "World");
@ -411,7 +411,7 @@ fn test_basic_line_break_anywhere_fallback_multi_line() {
None,
TextWrap::WordWrap,
)
.collect::<Vec<_>>();
.collect::<std::vec::Vec<_>>();
assert_eq!(lines.len(), 4);
assert_eq!(lines[0].line_text(text), "Hello");
assert_eq!(lines[1].line_text(text), "World");
@ -431,7 +431,7 @@ fn test_basic_line_break_anywhere_fallback_multi_line_char_wrap() {
None,
TextWrap::CharWrap,
)
.collect::<Vec<_>>();
.collect::<std::vec::Vec<_>>();
assert_eq!(lines.len(), 4);
assert_eq!(lines[0].line_text(text), "Hello");
assert_eq!(lines[1].line_text(text), "World");
@ -451,7 +451,7 @@ fn test_basic_line_break_anywhere_fallback_multi_line_v2() {
None,
TextWrap::WordWrap,
)
.collect::<Vec<_>>();
.collect::<std::vec::Vec<_>>();
assert_eq!(lines.len(), 4);
assert_eq!(lines[0].line_text(text), "Hello");
assert_eq!(lines[1].line_text(text), "W");
@ -471,7 +471,7 @@ fn test_basic_line_break_anywhere_fallback_max_lines() {
Some(3),
TextWrap::WordWrap,
)
.collect::<Vec<_>>();
.collect::<std::vec::Vec<_>>();
assert_eq!(lines.len(), 3);
assert_eq!(lines[0].line_text(text), "Hello");
assert_eq!(lines[1].line_text(text), "W");
@ -491,7 +491,7 @@ fn test_basic_line_break_space() {
None,
TextWrap::WordWrap,
)
.collect::<Vec<_>>();
.collect::<std::vec::Vec<_>>();
assert_eq!(lines.len(), 2);
assert_eq!(lines[0].line_text(text), "H");
assert_eq!(lines[1].line_text(text), "W");
@ -510,7 +510,7 @@ fn test_basic_line_break_space_char_wrap() {
None,
TextWrap::CharWrap,
)
.collect::<Vec<_>>();
.collect::<std::vec::Vec<_>>();
assert_eq!(lines.len(), 2);
assert_eq!(lines[0].line_text(text), "H");
assert_eq!(lines[1].line_text(text), "W");
@ -529,7 +529,7 @@ fn test_basic_line_break_space_v2() {
None,
TextWrap::WordWrap,
)
.collect::<Vec<_>>();
.collect::<std::vec::Vec<_>>();
assert_eq!(lines.len(), 2);
assert_eq!(lines[0].line_text(text), "B B");
assert_eq!(lines[1].line_text(text), "W");
@ -548,7 +548,7 @@ fn test_basic_line_break_space_v3() {
None,
TextWrap::WordWrap,
)
.collect::<Vec<_>>();
.collect::<std::vec::Vec<_>>();
assert_eq!(lines.len(), 2);
assert_eq!(lines[0].line_text(text), "H");
assert_eq!(lines[1].line_text(text), "W");
@ -567,7 +567,7 @@ fn test_basic_line_break_space_v4() {
None,
TextWrap::WordWrap,
)
.collect::<Vec<_>>();
.collect::<std::vec::Vec<_>>();
assert_eq!(lines.len(), 1);
assert_eq!(lines[0].line_text(text), "H W H");
}
@ -584,7 +584,7 @@ fn test_line_width_with_whitespace() {
None,
TextWrap::WordWrap,
)
.collect::<Vec<_>>();
.collect::<std::vec::Vec<_>>();
assert_eq!(lines.len(), 1);
assert_eq!(lines[0].text_width, text.len() as f32 * 10.);
}
@ -602,7 +602,7 @@ fn zero_width() {
TextWrap::WordWrap,
)
.map(|t| t.line_text(text))
.collect::<Vec<_>>();
.collect::<std::vec::Vec<_>>();
assert_eq!(lines, ["H", "e", "", "H", "e", "o"]);
}
@ -619,7 +619,7 @@ fn zero_width_char_wrap() {
TextWrap::CharWrap,
)
.map(|t| t.line_text(text))
.collect::<Vec<_>>();
.collect::<std::vec::Vec<_>>();
assert_eq!(lines, ["H", "e", "", "H", "e", "o"]);
}
@ -636,6 +636,6 @@ fn char_wrap_sentences() {
TextWrap::CharWrap,
)
.map(|t| t.line_text(text))
.collect::<Vec<_>>();
.collect::<std::vec::Vec<_>>();
assert_eq!(lines, ["Hello wo", "rld", "How are", "you?"]);
}

View file

@ -1,7 +1,6 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use core::ops::Range;

View file

@ -10,9 +10,7 @@
*/
#![warn(missing_docs)]
#[cfg(not(feature = "std"))]
use alloc::boxed::Box;
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use core::{
cell::{Cell, RefCell},
@ -424,10 +422,7 @@ impl TimerList {
}
}
#[cfg(all(not(feature = "std"), feature = "unsafe-single-threaded"))]
use crate::unsafe_single_threaded::thread_local;
thread_local!(static CURRENT_TIMERS : RefCell<TimerList> = RefCell::default());
crate::thread_local!(static CURRENT_TIMERS : RefCell<TimerList> = RefCell::default());
#[cfg(feature = "ffi")]
pub(crate) mod ffi {

View file

@ -118,6 +118,7 @@ mod formatter {
mod tests {
use super::format;
use core::fmt::Display;
use std::string::{String, ToString};
#[test]
fn test_format() {
assert_eq!(format("Hello", (&[]) as &[String]).to_string(), "Hello");
@ -198,14 +199,21 @@ pub fn translate(
}
#[cfg(all(target_family = "unix", feature = "gettext-rs"))]
fn translate_gettext(string: &str, ctx: &str, domain: &str, n: i32, plural: &str) -> String {
fn translate_gettext(
string: &str,
ctx: &str,
domain: &str,
n: i32,
plural: &str,
) -> std::string::String {
use std::string::String;
global_translation_property();
fn mangle_context(ctx: &str, s: &str) -> String {
format!("{}\u{4}{}", ctx, s)
std::format!("{}\u{4}{}", ctx, s)
}
fn demangle_context(r: String) -> String {
if let Some(x) = r.split('\u{4}').last() {
return x.to_owned();
return x.into();
}
r
}

View file

@ -20,10 +20,8 @@ use crate::lengths::{LogicalLength, LogicalPoint, LogicalRect, SizeLengths};
use crate::properties::{Property, PropertyTracker};
use crate::renderer::Renderer;
use crate::{Callback, Coord, SharedString, SharedVector};
#[cfg(not(feature = "std"))]
use alloc::boxed::Box;
use alloc::rc::{Rc, Weak};
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use core::cell::{Cell, RefCell};
use core::num::NonZeroU32;

View file

@ -47,7 +47,7 @@ fn r(x: i32, y: i32, w: i32, h: i32) -> LogicalRect {
#[cfg(test)]
#[track_caller]
fn fixed_placement(input: LogicalRect, expected: LogicalRect, clip: Option<LogicalRect>) {
eprintln!("fixed: {input:?}, clip({clip:?}) => {expected:?}");
std::eprintln!("fixed: {input:?}, clip({clip:?}) => {expected:?}");
let result = place_popup(Placement::Fixed(input.clone()), &clip);
if let Some(clip) = clip {
clip.contains_rect(&result);