Skip to main content

cranpose_services/
lib.rs

1#![deny(missing_docs)]
2#![doc = include_str!("../README.md")]
3
4#[cfg(test)]
5use cranpose_core::{Composition, MemoryApplier, location_key};
6
7pub mod accessibility_options;
8pub mod accessibility_state;
9pub mod app_info;
10pub mod app_update;
11pub mod async_io;
12pub mod audio;
13pub mod background;
14pub mod browser_history;
15pub mod bundled_assets;
16pub mod camera;
17mod composition_locals;
18pub mod content;
19pub mod device_info;
20mod durable_save;
21pub mod file_picker;
22#[cfg(not(target_arch = "wasm32"))]
23pub mod github_release_updater;
24pub mod haptics;
25pub mod heart_rate;
26#[cfg(not(target_arch = "wasm32"))]
27mod helper_process;
28pub mod host;
29pub mod host_messages;
30pub mod host_surface;
31/// HTTP requests, downloads and the client that sends them.
32pub mod http;
33#[cfg(feature = "image-loading")]
34pub mod image_loading;
35pub mod image_picker;
36mod inbox;
37pub mod incoming_share;
38pub mod launch_args;
39pub mod launcher;
40pub mod media;
41pub mod memory_pressure;
42pub mod microphone_permission;
43pub mod microphone_standby;
44pub mod navigation;
45pub mod network_status;
46pub mod notifier;
47pub mod opened_links;
48#[cfg(not(target_arch = "wasm32"))]
49pub mod peer;
50pub mod power;
51pub mod preferences;
52pub mod purchases;
53mod registry;
54mod retain;
55pub mod share_sheet;
56pub mod storage;
57/// The light or dark appearance of the operating system.
58pub mod theme;
59mod thread_state;
60/// Opening a URI, such as a web link, in the application the platform picks for it.
61pub mod uri_handler;
62pub mod wearable;
63pub mod wearable_framed;
64pub mod writable_folder;
65
66pub use accessibility_options::{
67    AccessibilityOptions, ProvideAccessibilityOptions, local_accessibility_options,
68    platform_accessibility_options, set_platform_accessibility_options,
69};
70pub use accessibility_state::{
71    AccessibilityState, ProvideAccessibilityState, local_accessibility_state,
72    platform_accessibility_state, set_platform_accessibility_state,
73};
74pub use app_info::{
75    AppInfo, AppInfoRef, app_info, build_version, clear_platform_app_info, set_platform_app_info,
76    version_name,
77};
78pub use app_update::{
79    AppUpdateCapabilities, AppUpdateError, AppUpdateObserver, AppUpdateStatus, AppUpdater,
80    AppUpdaterRef, DigestAlgorithm, DigestVerifier, GitHubReleaseUpdate, PackageDigest,
81    UpdatePackage, app_update_capabilities, app_update_checks_supported, app_update_status,
82    app_updates_supported, check_for_app_update, clear_platform_app_updater, install_app_update,
83    observe_app_update_status, set_app_update_status, set_platform_app_updater, sha256_hex,
84    verify_package,
85};
86pub use async_io::{ChunkChannel, ChunkNext, ChunkStream, MAX_PENDING_CHUNKS, Signal, SignalWait};
87pub use audio::{
88    AudioBus, AudioClip, AudioError, AudioPlayer, AudioPlayerRef, NoopAudioPlayer, PlaybackParams,
89    ProvideAudio, SoundBank, SoundBankEntry, SoundBankFailure, SoundId, SoundSpec, VoiceId,
90    clear_platform_audio, default_audio, local_audio, rememberSoundBank, set_platform_audio,
91};
92pub use background::{
93    BackgroundActivity, BackgroundActivityRef, BackgroundWork, BackgroundWorkLease,
94    acquire_background_work, background_active, background_activity,
95    clear_platform_background_activity, set_platform_background_activity,
96};
97pub use browser_history::{
98    BrowserHistory, BrowserHistoryObserver, BrowserHistoryRef, browser_history,
99    clear_platform_browser_history, set_platform_browser_history,
100};
101#[cfg(not(target_arch = "wasm32"))]
102pub use bundled_assets::{
103    BundledAssetEntry, BundledAssetInstallOutcome, BundledAssetInstallSpec,
104    install_bundled_asset_set,
105};
106pub use bundled_assets::{
107    BundledAssetError, BundledAssetReader, BundledAssets, BundledAssetsRef, StreamingAssetReader,
108    bundled_assets, clear_platform_bundled_assets, set_platform_bundled_assets,
109};
110pub use camera::{
111    Camera, CameraError, CameraFrame, CameraLens, CameraLenses, CameraObserver, CameraRef,
112    CameraState, CameraStill, FlashMode, FrameFormat, LensFacing, UprightRgba, camera,
113    camera_lenses, camera_state, camera_supported, capture_camera_still, clear_platform_camera,
114    dropped_camera_frames, latest_camera_frame, observe_camera_frames, observe_camera_lenses,
115    observe_camera_state, observe_camera_stills, publish_camera_frame, publish_camera_lenses,
116    publish_camera_state, publish_camera_still, record_dropped_camera_frame, rememberCameraFrames,
117    rememberCameraLenses, rememberCameraState, rememberCameraStills, request_camera_still,
118    set_platform_camera, start_camera, stop_camera,
119};
120#[cfg(not(target_arch = "wasm32"))]
121pub use content::{
122    BlockingSink, FileContent, FileFolder, FileSink, copy_content, file_content, file_folder,
123    open_threaded, read_full, run_threaded, threaded_sink,
124};
125pub use content::{
126    BytesContent, Content, ContentChannel, ContentEntry, ContentError, ContentFolder,
127    ContentFolderRef, ContentFuture, ContentHandle, ContentMetadata, ContentReader,
128    ContentReaderRef, ContentResolver, ContentResolverRef, ContentSink, ContentSinkRef,
129    ContentStream, ContentStreamRef, DEFAULT_CHUNK_LEN, ReadyFolder,
130    clear_platform_content_resolver, collect_stream, drain_reader, folder_files, percent_decode,
131    percent_decode_lossy, resolve_content, set_platform_content_resolver, write_all,
132};
133pub use device_info::{
134    DeviceInfo, DeviceInfoRef, clear_platform_device_info, device_info, release_free_memory,
135    set_platform_device_info,
136};
137pub use durable_save::SaveableRegistration;
138pub use file_picker::{
139    FileFilter, FilePicker, FilePickerError, FilePickerOptions, FilePickerRef, PickerFuture,
140    ProvideFilePicker, RecoveredPick, SaveDocumentRequest, clear_platform_file_picker,
141    default_file_picker, local_file_picker, set_platform_file_picker,
142};
143#[cfg(not(target_arch = "wasm32"))]
144pub use github_release_updater::GitHubAppUpdater;
145pub use haptics::{
146    HapticEffect, HapticError, HapticFeedback, HapticPattern, Haptics, HapticsRef, ProvideHaptics,
147    clear_platform_haptics, default_haptics, local_haptics, set_platform_haptics,
148};
149pub use heart_rate::{
150    HeartRate, HeartRateError, HeartRateMonitor, HeartRateMonitorRef, HeartRatePermission,
151    HeartRateReader, HeartRateStatus, clear_platform_heart_rate, heart_rate, heart_rate_available,
152    heart_rate_permission, observe_heart_rate, publish_heart_rate, publish_heart_rate_permission,
153    rememberHeartRate, request_heart_rate_permission, set_platform_heart_rate,
154};
155#[cfg(not(target_arch = "wasm32"))]
156pub use helper_process::windowless_command;
157pub use host::{
158    DEFAULT_DURABLE_SAVE_DEADLINE, DurableSaveEffect, DurableSaveError, DurableSaveOutcome,
159    DurableSaveRegistration, HostController, HostControllerRef, LifecycleEvent, LifecycleObserver,
160    LifecycleState, PlatformDirectories, PlatformDirectoryError, ProvideLifecycle,
161    advance_lifecycle, application_directories, application_id, background_app,
162    clear_application_id, clear_host_controller, current_lifecycle_state, dispatch_lifecycle,
163    dispatch_lifecycle_state, durable_save_deadline, exit_app, host_controller,
164    local_lifecycle_state, observe_lifecycle, register_durable_save, register_preference_save,
165    rememberLifecycleEvents, rememberLifecycleState, run_durable_saves, set_application_id,
166    set_host_controller, set_keep_screen_on, window_lifecycle_state,
167};
168pub use host_messages::{
169    HostMessage, HostMessageObserver, clear_host_messages, clear_host_outbox, install_host_outbox,
170    observe_host_messages, publish_host_message, rememberHostMessages, send_to_host,
171};
172pub use host_surface::{
173    HostSurface, HostSurfaceObserver, HostSurfaceRef, HostSurfaceSize, ResizeRefused,
174    clear_platform_host_surface, host_surface, host_surface_size, observe_host_surface_size,
175    publish_host_surface_size, rememberHostSurfaceSize, request_host_surface_size,
176    set_platform_host_surface,
177};
178pub use http::{
179    BytesBody, CancelTransfer, HttpBody, HttpBodyRef, HttpClient, HttpClientRef, HttpControl,
180    HttpError, HttpFuture, HttpMethod, HttpProgress, HttpRequest, HttpResponse, ProgressHandler,
181    StubAnswer, StubHttpClient, default_http_client, http_body_ref, local_http_client,
182    map_ordered_concurrent,
183};
184#[cfg(not(target_arch = "wasm32"))]
185pub use http::{PlatformDownloader, downloaded_length, set_platform_downloader};
186#[cfg(feature = "image-loading")]
187pub use image_loading::{
188    ImageCacheLimits, ImageLoadError, ImageLoadState, ImageLoader, ImageRequest, image_loader,
189    rememberAsyncImage,
190};
191pub use image_picker::{
192    IMAGE_EXTENSIONS, ImagePicker, ImagePickerError, ImagePickerRef, ImageSource,
193    ProvideImagePicker, clear_platform_image_picker, default_image_picker, local_image_picker,
194    set_platform_image_picker,
195};
196pub use inbox::InboxObserver;
197pub use incoming_share::{
198    IncomingContent, IncomingSource, clear_incoming_content, observe_incoming_content,
199    publish_incoming_content, rememberIncomingContent,
200};
201pub use launch_args::{
202    LaunchArgValue, LaunchArgs, LaunchArgsRef, ProvideLaunchArgs, clear_platform_launch_args,
203    is_debuggable, isDebuggable, launch_args, launch_args_from_command_line, local_launch_args,
204    set_platform_launch_args,
205};
206pub use launcher::{
207    ExportFileLauncher, LauncherResult, OpenFileLauncher, OpenFilesLauncher, OpenFolderLauncher,
208    SaveDocumentLauncher, WritableFolderLauncher, clear_launcher_state, rememberExportFileLauncher,
209    rememberOpenFileLauncher, rememberOpenFilesLauncher, rememberOpenFolderLauncher,
210    rememberSaveDocumentLauncher, rememberWritableFolderLauncher,
211};
212pub use media::{
213    AudioFocus, DUCKED_GAIN, EqualizerBand, EqualizerSettings, MediaArtwork, MediaCapabilities,
214    MediaCommand, MediaError, MediaItem, MediaMetadata, MediaObserver, MediaPlayer, MediaPlayerRef,
215    MediaSamples, MediaSourceHandle, MediaSourceOpener, MediaSourceOpenerRef,
216    OCTAVE_BAND_CENTERS_HZ, PlaybackProgress, PlaybackState, audio_focus,
217    clear_platform_media_player, clear_platform_media_source_opener, current_media_item,
218    dropped_media_samples, latest_media_samples, media_capabilities, media_equalizer,
219    media_equalizer_bands, media_playback_supported, media_player, media_volume,
220    observe_audio_focus, observe_media_commands, observe_media_samples, observe_playback_progress,
221    observe_playback_state, octave_equalizer_bands, open_media, open_media_source, path_from_uri,
222    pause_media, play_media, playback_progress, playback_state, probe_media_duration,
223    publish_audio_focus, publish_media_command, publish_media_samples, publish_playback_progress,
224    publish_playback_state, record_dropped_media_samples, rememberAudioFocus,
225    rememberMediaCommands, rememberMediaSamples, rememberPlaybackProgress, rememberPlaybackState,
226    seek_media, seek_media_fraction, set_media_analysis_enabled, set_media_balance,
227    set_media_equalizer, set_media_looping, set_media_metadata, set_media_speed, set_media_volume,
228    set_platform_media_player, set_platform_media_source_opener, stop_media, toggle_media,
229    uri_for_path,
230};
231pub use memory_pressure::{
232    MemoryPressure, MemoryPressureObserver, observe_memory_pressure, publish_memory_pressure,
233    rememberMemoryPressure,
234};
235pub use microphone_permission::{
236    MicrophoneAccess, MicrophonePermission, MicrophonePermissionObserver, PreparedMicrophone,
237    microphone_permission, observe_microphone_permission, open_microphone_settings,
238    prepare_microphone, publish_microphone_permission, rememberMicrophonePermission,
239    request_microphone_permission, set_platform_microphone_access,
240};
241pub use microphone_standby::{
242    MicrophoneStandby, MicrophoneStandbyLease, StandbyNotice, hold_microphone_standby,
243    microphone_standby_available, microphone_standby_stopped, on_microphone_standby_stop,
244    set_microphone_standby_notice, set_platform_microphone_standby,
245};
246pub use navigation::{
247    BackEdge, BackEvent, BackGesture, BackHandler, BackRequestObserver, PredictiveBackHandler,
248    back_interception_enabled, exit_requested, observe_back_requests, push_back_gesture,
249    push_back_request, request_exit, set_back_interception, take_back_requests, take_exit_request,
250};
251pub use network_status::{
252    Connectivity, Metering, NetworkMonitor, NetworkMonitorRef, NetworkStatus,
253    clear_platform_network_monitor, network_monitor, network_status, set_platform_network_monitor,
254};
255pub use notifier::{
256    Notifier, NotifierRef, NotifyRequest, ProvideNotifier, clear_platform_notifier,
257    default_notifier, local_notifier, set_platform_notifier,
258};
259pub use opened_links::{
260    clear_opened_links, observe_opened_links, publish_opened_link, rememberOpenedLinks,
261};
262#[cfg(not(target_arch = "wasm32"))]
263pub use peer::{
264    ByteSource, BytesSource, FetchResult, PeerError, PeerServer, SourceResolver, content_length,
265    fetch_range, fetch_to_writer,
266};
267pub use power::{
268    BatteryStatus, PowerCapabilities, PowerMonitor, PowerMonitorRef, PowerObserverRegistration,
269    PowerReading, PowerState, ThermalState, clear_platform_power_monitor, observe_power_state,
270    power_capabilities, power_monitor, power_state, publish_power_state, rememberPowerState,
271    set_platform_power_monitor,
272};
273#[cfg(all(target_arch = "wasm32", feature = "preferences-web"))]
274pub use preferences::BrowserPreferences;
275#[cfg(not(target_arch = "wasm32"))]
276pub use preferences::FilePreferences;
277pub use preferences::{
278    MemoryPreferences, PreferencesError, PreferencesRef, PreferencesStore, ProvideSaveableScope,
279    SaveableScope, Saver, clear_platform_preferences, preferences, rememberSaveable,
280    set_platform_preferences,
281};
282pub use purchases::{
283    Product, PurchaseEvent, Purchases, PurchasesRef, StoreObserver, StorePhase, StoreState,
284    clear_platform_purchases, note_store_news, observe_store_news, purchases,
285    rememberPurchaseEvents, rememberStoreState, set_platform_purchases, store_available,
286    store_state,
287};
288pub use retain::retain;
289pub use share_sheet::{
290    ProvideShareSheet, ShareContent, ShareError, ShareSheet, ShareSheetRef,
291    clear_platform_share_sheet, default_share_sheet, local_share_sheet, set_platform_share_sheet,
292};
293pub use storage::{StorageSpace, StorageSpaceRef, available_storage, set_platform_storage_space};
294pub use theme::{
295    ProvideSystemTheme, SystemTheme, clear_platform_system_theme, default_system_theme,
296    isSystemInDarkTheme, known_system_theme, local_system_theme, set_platform_system_theme,
297};
298pub use uri_handler::{
299    ProvideUriHandler, UriHandler, UriHandlerError, UriHandlerRef, clear_platform_uri_handler,
300    default_uri_handler, local_uri_handler, set_platform_uri_handler,
301};
302pub use wearable::{
303    WearableError, WearableEvent, WearableLink, WearablePeer, WearableReceiver, WearableStream,
304    open_on_wearable_peer, open_wearable_stream, publish_wearable_event, send_wearable_message,
305    set_platform_wearable_link, set_wearable_receiver, wearable_peers,
306};
307pub use wearable_framed::{FramedWearableLink, WearableTransport};
308pub use writable_folder::{
309    FolderEntry, FolderError, FolderReader, FolderWriter, WritableFolderStore,
310    WritableFolderStoreRef, open_writable_folder, set_writable_folder_store_factory,
311};
312
313#[cfg(test)]
314pub(crate) type TestComposition = Composition<MemoryApplier>;
315
316#[cfg(test)]
317pub(crate) fn test_scratch_dir(tag: &str) -> std::path::PathBuf {
318    cranpose_core::test_scratch_dir(env!("CARGO_MANIFEST_DIR"), tag)
319}
320
321#[cfg(test)]
322pub(crate) fn run_test_composition(build: impl FnMut()) -> TestComposition {
323    let mut composition = Composition::new(MemoryApplier::new());
324    composition
325        .render(location_key(file!(), line!(), column!()), build)
326        .expect("initial render succeeds");
327    composition
328}
329
330/// What a composable read while a test composition ran once, or `None` when
331/// the read never ran.
332#[cfg(test)]
333pub(crate) fn captured_in_composition<T: Copy + 'static>(
334    read: impl Fn() -> T + 'static,
335) -> Option<T> {
336    let captured = std::rc::Rc::new(std::cell::Cell::new(None));
337    let sink = std::rc::Rc::clone(&captured);
338    run_test_composition(move || sink.set(Some(read())));
339    captured.get()
340}