🎯 Ejemplos recomendados
Balanced sample collections from various categories for you to explore
Ejemplos de Características Móviles Web Rust
Ejemplos de características móviles Web Rust incluyendo información del dispositivo, estado de red y retroalimentación háptica
💻 Información del Dispositivo rust
🟢 simple
⭐⭐⭐
Obtener información del dispositivo usando APIs del navegador
⏱️ 20 min
🏷️ rust, web, mobile features
Prerequisites:
Basic Rust, Understanding of Web APIs
// Web Rust Device Information Examples
// Device information detection using browser Web APIs
//
// This demonstrates device info detection that would work in WebAssembly (WASM) context
//
// In WASM, you would use JavaScript interop with:
// - navigator.userAgent
// - window.screen
// - navigator.deviceMemory
// - navigator.hardwareConcurrency
// - window.matchMedia
use serde::{Deserialize, Serialize};
// 1. Device Information Structure
/// Device information
#[derive(Debug, Clone, Serialize, Deserialize)]
struct DeviceInfo {
user_agent: String,
platform: String,
vendor: String,
language: String,
cookies_enabled: bool,
on_line: bool,
hardware_concurrency: u32,
device_memory: Option<u32>,
max_touch_points: u32,
}
/// Screen information
#[derive(Debug, Clone, Serialize, Deserialize)]
struct ScreenInfo {
width: u32,
height: u32,
avail_width: u32,
avail_height: u32,
color_depth: u32,
pixel_depth: u32,
device_pixel_ratio: f64,
orientation: String,
}
/// Viewport information
#[derive(Debug, Clone, Serialize, Deserialize)]
struct ViewportInfo {
width: u32,
height: u32,
scroll_x: f64,
scroll_y: f64,
}
// 2. Device Detection
/// Detect if device is mobile
fn is_mobile(user_agent: &str) -> bool {
let mobile_keywords = [
"android", "iphone", "ipad", "ipod", "windows phone",
"blackberry", "mobile", "webos", "opera mini"
];
let lower = user_agent.to_lowercase();
mobile_keywords.iter().any(|&keyword| lower.contains(keyword))
}
/// Detect device type
#[derive(Debug, Clone, PartialEq, Eq)]
enum DeviceType {
Desktop,
Mobile,
Tablet,
Unknown,
}
fn detect_device_type(user_agent: &str, screen_width: u32) -> DeviceType {
let lower = user_agent.to_lowercase();
if lower.contains("ipad") || lower.contains("tablet") {
DeviceType::Tablet
} else if is_mobile(user_agent) {
// Check screen size for better tablet detection
if screen_width >= 768 {
DeviceType::Tablet
} else {
DeviceType::Mobile
}
} else {
DeviceType::Desktop
}
}
/// Detect operating system
#[derive(Debug, Clone, PartialEq, Eq)]
enum OperatingSystem {
Windows,
MacOS,
Linux,
Android,
IOS,
Unknown,
}
fn detect_os(user_agent: &str) -> OperatingSystem {
let lower = user_agent.to_lowercase();
if lower.contains("windows") {
OperatingSystem::Windows
} else if lower.contains("mac os x") || lower.contains("macos") {
OperatingSystem::MacOS
} else if lower.contains("linux") && !lower.contains("android") {
OperatingSystem::Linux
} else if lower.contains("android") {
OperatingSystem::Android
} else if lower.contains("iphone") || lower.contains("ipad") || lower.contains("ipod") {
OperatingSystem::IOS
} else {
OperatingSystem::Unknown
}
}
/// Detect browser
#[derive(Debug, Clone, PartialEq, Eq)]
enum Browser {
Chrome,
Firefox,
Safari,
Edge,
Opera,
Unknown,
}
fn detect_browser(user_agent: &str) -> Browser {
let lower = user_agent.to_lowercase();
if lower.contains("edg") {
Browser::Edge
} else if lower.contains("opr") || lower.contains("opera") {
Browser::Opera
} else if lower.contains("chrome") && !lower.contains("edg") {
Browser::Chrome
} else if lower.contains("firefox") {
Browser::Firefox
} else if lower.contains("safari") && !lower.contains("chrome") {
Browser::Safari
} else {
Browser::Unknown
}
}
// 3. Feature Detection
/// Check for touch support
fn has_touch_support() -> bool {
// In WASM, would check: ('ontouchstart' in window) || (navigator.maxTouchPoints > 0)
true // Simulated
}
/// Check for WebGL support
fn has_webgl_support() -> bool {
// In WASM, would check for WebGL context
true // Simulated
}
/// Check for localStorage support
fn has_local_storage() -> bool {
// In WASM, would try to access localStorage
true // Simulated
}
/// Check for service worker support
fn has_service_worker() -> bool {
// In WASM, would check: 'serviceWorker' in navigator
true // Simulated
}
/// Check for web worker support
fn has_web_worker() -> bool {
// In WASM, would check: 'Worker' in window
true // Simulated
}
/// Check for geolocation support
fn has_geolocation() -> bool {
// In WASM, would check: 'geolocation' in navigator
true // Simulated
}
// 4. Capability Information
/// Device capabilities
#[derive(Debug, Clone, Serialize, Deserialize)]
struct DeviceCapabilities {
touch_support: bool,
webgl: bool,
local_storage: bool,
session_storage: bool,
service_worker: bool,
web_worker: bool,
geolocation: bool,
web_socket: bool,
webrtc: bool,
}
impl DeviceCapabilities {
fn new() -> Self {
DeviceCapabilities {
touch_support: has_touch_support(),
webgl: has_webgl_support(),
local_storage: has_local_storage(),
session_storage: has_local_storage(), // Usually same as localStorage
service_worker: has_service_worker(),
web_worker: has_web_worker(),
geolocation: has_geolocation(),
web_socket: true, // Generally available
webrtc: true, // Would need actual check
}
}
}
// 5. Battery Information
/// Battery information
#[derive(Debug, Clone, Serialize, Deserialize)]
struct BatteryInfo {
level: f64,
charging: bool,
charging_time: Option<i32>,
discharging_time: Option<i32>,
}
// Battery API is not available in all browsers, this is a mock
fn get_battery_info() -> Option<BatteryInfo> {
// In WASM, would use: navigator.getBattery()
Some(BatteryInfo {
level: 0.85,
charging: true,
charging_time: Some(3600),
discharging_time: None,
})
}
// 6. Network Information
/// Connection type
#[derive(Debug, Clone, PartialEq, Eq)]
enum ConnectionType {
Bluetooth,
Cellular,
Ethernet,
None,
Wifi,
Wimax,
Other,
Unknown,
}
/// Network information
#[derive(Debug, Clone, Serialize, Deserialize)]
struct NetworkInfo {
type_: ConnectionType,
effective_type: String,
downlink: f64,
rtt: u32,
save_data: bool,
}
// Network Information API is experimental
fn get_network_info() -> Option<NetworkInfo> {
// In WASM, would use: navigator.connection
Some(NetworkInfo {
type_: ConnectionType::Wifi,
effective_type: "4g".to_string(),
downlink: 10.0,
rtt: 50,
save_data: false,
})
}
// 7. Media Devices
/// Media device information
#[derive(Debug, Clone, Serialize, Deserialize)]
struct MediaDevices {
has_camera: bool,
has_microphone: bool,
has_speakers: bool,
camera_count: u32,
microphone_count: u32,
}
// Media Devices API requires permissions
async fn get_media_devices() -> MediaDevices {
// In WASM, would use: navigator.mediaDevices.enumerateDevices()
MediaDevices {
has_camera: true,
has_microphone: true,
has_speakers: true,
camera_count: 1,
microphone_count: 1,
}
}
// 8. Orientation Detection
/// Device orientation
#[derive(Debug, Clone, PartialEq, Eq)]
enum Orientation {
Portrait,
Landscape,
}
fn get_orientation(screen_width: u32, screen_height: u32) -> Orientation {
if screen_width > screen_height {
Orientation::Landscape
} else {
Orientation::Portrait
}
}
// 9. Device Information Collector
/// Complete device information
#[derive(Debug, Clone, Serialize, Deserialize)]
struct CompleteDeviceInfo {
device: DeviceInfo,
screen: ScreenInfo,
viewport: ViewportInfo,
device_type: DeviceType,
os: OperatingSystem,
browser: Browser,
capabilities: DeviceCapabilities,
battery: Option<BatteryInfo>,
network: Option<NetworkInfo>,
}
impl CompleteDeviceInfo {
fn collect() -> Self {
// Simulated data - in WASM would use actual browser APIs
CompleteDeviceInfo {
device: DeviceInfo {
user_agent: "Mozilla/5.0 (WebAssembly Simulator)".to_string(),
platform: "Web".to_string(),
vendor: "Unknown".to_string(),
language: "en-US".to_string(),
cookies_enabled: true,
on_line: true,
hardware_concurrency: 8,
device_memory: Some(8),
max_touch_points: 5,
},
screen: ScreenInfo {
width: 1920,
height: 1080,
avail_width: 1920,
avail_height: 1050,
color_depth: 24,
pixel_depth: 24,
device_pixel_ratio: 1.0,
orientation: "landscape-primary".to_string(),
},
viewport: ViewportInfo {
width: 1920,
height: 1080,
scroll_x: 0.0,
scroll_y: 0.0,
},
device_type: DeviceType::Desktop,
os: OperatingSystem::Unknown,
browser: Browser::Unknown,
capabilities: DeviceCapabilities::new(),
battery: get_battery_info(),
network: get_network_info(),
}
}
}
// 10. User Preference Detection
/// Color scheme preference
#[derive(Debug, Clone, PartialEq, Eq)]
enum ColorScheme {
Light,
Dark,
NoPreference,
}
fn get_preferred_color_scheme() -> ColorScheme {
// In WASM, would use: window.matchMedia('(prefers-color-scheme: dark)').matches
ColorScheme::NoPreference
}
/// Reduced motion preference
fn prefers_reduced_motion() -> bool {
// In WASM, would use: window.matchMedia('(prefers-reduced-motion: reduce)').matches
false
}
/// High contrast preference
fn prefers_high_contrast() -> bool {
// In WASM, would use: window.matchMedia('(prefers-contrast: high)').matches
false
}
// Usage Examples
fn main() {
println!("=== Web Rust Device Information Examples ===\n");
// 1. Device detection
println!("--- 1. Device Detection ---");
let user_agent = "Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X)";
println!("Is mobile: {}", is_mobile(user_agent));
println!("Device type: {:?}", detect_device_type(user_agent, 375));
println!("OS: {:?}", detect_os(user_agent));
println!("Browser: {:?}", detect_browser(user_agent));
// 2. Complete device info
println!("
--- 2. Complete Device Info ---");
let device_info = CompleteDeviceInfo::collect();
println!("{:?}", device_info);
// 3. Capabilities
println!("
--- 3. Device Capabilities ---");
let caps = DeviceCapabilities::new();
println!("Touch support: {}", caps.touch_support);
println!("WebGL: {}", caps.webgl);
println!("Service Worker: {}", caps.service_worker);
println!("Geolocation: {}", caps.geolocation);
// 4. Battery
println!("
--- 4. Battery Information ---");
if let Some(battery) = get_battery_info() {
println!("Level: {}%", battery.level * 100.0);
println!("Charging: {}", battery.charging);
}
// 5. Network
println!("
--- 5. Network Information ---");
if let Some(network) = get_network_info() {
println!("Type: {:?}", network.type_);
println!("Effective type: {}", network.effective_type);
println!("Downlink: {} Mbps", network.downlink);
}
// 6. Orientation
println!("
--- 6. Orientation ---");
println!("Current orientation: {:?}", get_orientation(1920, 1080));
println!("Portrait orientation: {:?}", get_orientation(375, 667));
// 7. User preferences
println!("
--- 7. User Preferences ---");
println!("Color scheme: {:?}", get_preferred_color_scheme());
println!("Reduced motion: {}", prefers_reduced_motion());
println!("High contrast: {}", prefers_high_contrast());
println!("
=== Note ===");
println!("These examples demonstrate API patterns for WASM environments.");
println!("Actual implementation requires JavaScript interop with browser APIs.");
println!("
=== All Device Information Examples Completed ===");
}
💻 Retroalimentación Háptica rust
🟢 simple
⭐⭐⭐
Vibración y retroalimentación háptica usando la API de Vibración del navegador
⏱️ 20 min
🏷️ rust, web, mobile features
Prerequisites:
Basic Rust, Understanding of Web APIs
// Web Rust Haptic Feedback Examples
// Vibration and haptic feedback using browser Vibration API
//
// This demonstrates haptic feedback that would work in WebAssembly (WASM) context
//
// In WASM, you would use JavaScript interop with:
// - navigator.vibrate()
// - navigator.vibrate([pattern])
//
// Note: Vibration API is not available in all browsers and platforms
use std::time::Duration;
// 1. Vibration Patterns
/// Simple vibration
pub fn vibrate(duration_ms: u32) -> bool {
// In WASM: navigator.vibrate(duration_ms)
println!("Vibrating for {}ms", duration_ms);
true // Simulated success
}
/// Vibration pattern (on/off in milliseconds)
pub fn vibrate_pattern(pattern: &[u32]) -> bool {
// In WASM: navigator.vibrate(pattern)
println!("Vibrating with pattern: {:?}", pattern);
true // Simulated success
}
/// Stop vibration
pub fn stop_vibration() -> bool {
// In WASM: navigator.vibrate(0)
println!("Stopping vibration");
true // Simulated success
}
// 2. Common Haptic Patterns
/// Success notification
pub fn vibrate_success() -> bool {
// Two short pulses
vibrate_pattern(&[100, 50, 100])
}
/// Error notification
pub fn vibrate_error() -> bool {
// Three short pulses
vibrate_pattern(&[100, 50, 100, 50, 100])
}
/// Warning notification
pub fn vibrate_warning() -> bool {
// Long pulse
vibrate(500)
}
/// Notification (default)
pub fn vibrate_notification() -> bool {
// Short pulse
vibrate(200)
}
// 3. Feedback Types
/// Type of haptic feedback
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FeedbackType {
LightTap,
MediumTap,
HeavyTap,
Success,
Warning,
Error,
SelectionChanged,
Confirm,
Cancel,
}
impl FeedbackType {
/// Get vibration pattern for feedback type
pub fn pattern(&self) -> Vec<u32> {
match self {
FeedbackType::LightTap => vec![10],
FeedbackType::MediumTap => vec![30],
FeedbackType::HeavyTap => vec![50],
FeedbackType::Success => vec![100, 50, 100],
FeedbackType::Warning => vec![500],
FeedbackType::Error => vec![100, 50, 100, 50, 100],
FeedbackType::SelectionChanged => vec![20],
FeedbackType::Confirm => vec![100, 50, 100],
FeedbackType::Cancel => vec![50, 30, 50],
}
}
/// Execute the feedback
pub fn execute(&self) -> bool {
vibrate_pattern(&self.pattern())
}
}
// 4. Haptic Feedback Manager
/// Manager for haptic feedback
pub struct HapticManager {
enabled: bool,
intensity: f64, // 0.0 to 1.0
}
impl HapticManager {
pub fn new() -> Self {
HapticManager {
enabled: true,
intensity: 1.0,
}
}
/// Enable or disable haptics
pub fn set_enabled(&mut self, enabled: bool) {
self.enabled = enabled;
}
/// Set intensity (0.0 to 1.0)
pub fn set_intensity(&mut self, intensity: f64) {
self.intensity = intensity.max(0.0).min(1.0);
}
/// Execute feedback with intensity adjustment
pub fn feedback(&self, feedback_type: FeedbackType) -> bool {
if !self.enabled {
return false;
}
let mut pattern = feedback_type.pattern();
// Adjust pattern based on intensity
for duration in &mut pattern {
*duration = (*duration as f64 * self.intensity) as u32;
}
vibrate_pattern(&pattern)
}
/// Tap feedback
pub fn tap(&self, strength: u32) -> bool {
if !self.enabled {
return false;
}
let duration = (strength as f64 * self.intensity) as u32;
vibrate(duration)
}
}
impl Default for HapticManager {
fn default() -> Self {
Self::new()
}
}
// 5. Advanced Patterns
/// Heartbeat pattern
pub fn vibrate_heartbeat(count: u32) -> bool {
let mut pattern = Vec::new();
for _ in 0..count {
pattern.extend_from_slice(&[50, 50, 100, 200]);
}
vibrate_pattern(&pattern)
}
/// Rising intensity
pub fn vibrate_rising() -> bool {
vibrate_pattern(&[50, 50, 100, 50, 150, 50, 200, 50, 250])
}
/// Falling intensity
pub fn vibrate_falling() -> bool {
vibrate_pattern(&[250, 50, 200, 50, 150, 50, 100, 50, 50])
}
/// SOS pattern (three short, three long, three short)
pub fn vibrate_sos() -> bool {
vibrate_pattern(&[
100, 50, 100, 50, 100, 100,
300, 100, 300, 100, 300, 100,
100, 50, 100, 50, 100, 200,
])
}
/// Double tap
pub fn vibrate_double_tap() -> bool {
vibrate_pattern(&[50, 100, 50])
}
/// Triple tap
pub fn vibrate_triple_tap() -> bool {
vibrate_pattern(&[50, 50, 50, 50, 50])
}
/// Tick-tock (clock-like)
pub fn vibrate_tick_tock() -> bool {
let mut pattern = Vec::new();
for _ in 0..5 {
pattern.extend_from_slice(&[50, 150]);
}
vibrate_pattern(&pattern)
}
/// Knock (door knock)
pub fn vibrate_knock() -> bool {
vibrate_pattern(&[100, 100, 100, 200, 300, 300])
}
/// Typing rhythm
pub fn vibrate_typing() -> bool {
vibrate_pattern(&[30, 50, 30, 50, 30, 50, 30])
}
/// Alarm-like
pub fn vibrate_alarm(count: u32) -> bool {
let mut pattern = Vec::new();
for _ in 0..count {
pattern.extend_from_slice(&[500, 500]);
}
vibrate_pattern(&pattern)
}
// 6. Contextual Feedback
/// UI interaction feedback
pub struct UIFeedback {
manager: HapticManager,
}
impl UIFeedback {
pub fn new() -> Self {
UIFeedback {
manager: HapticManager::new(),
}
}
/// Button press
pub fn button_press(&self) -> bool {
self.manager.feedback(FeedbackType::MediumTap)
}
/// Toggle on
pub fn toggle_on(&self) -> bool {
self.manager.feedback(FeedbackType::Success)
}
/// Toggle off
pub fn toggle_off(&self) -> bool {
self.manager.feedback(FeedbackType::LightTap)
}
/// Selection changed
pub fn selection_changed(&self) -> bool {
self.manager.feedback(FeedbackType::SelectionChanged)
}
/// Confirm action
pub fn confirm(&self) -> bool {
self.manager.feedback(FeedbackType::Confirm)
}
/// Cancel action
pub fn cancel(&self) -> bool {
self.manager.feedback(FeedbackType::Cancel)
}
/// Invalid action
pub fn invalid(&self) -> bool {
self.manager.feedback(FeedbackType::Error)
}
}
impl Default for UIFeedback {
fn default() -> Self {
Self::new()
}
}
// 7. Gaming Feedback
/// Gaming haptic feedback
pub struct GameHaptics {
manager: HapticManager,
}
impl GameHaptics {
pub fn new() -> Self {
GameHaptics {
manager: HapticManager::new(),
}
}
/// Button tap
pub fn button_tap(&self) -> bool {
self.manager.tap(30)
}
/// Action button
pub fn action_button(&self) -> bool {
self.manager.tap(50)
}
/// Impact (collision, etc.)
pub fn impact(&self, strength: u32) -> bool {
self.manager.tap(strength)
}
/// Power-up
pub fn powerup(&self) -> bool {
vibrate_rising()
}
/// Achievement unlocked
pub fn achievement(&self) -> bool {
self.manager.feedback(FeedbackType::Success)
}
/// Damage received
pub fn damage(&self) -> bool {
self.manager.feedback(FeedbackType::HeavyTap)
}
/// Death
pub fn death(&self) -> bool {
self.manager.feedback(FeedbackType::Error)
}
}
impl Default for GameHaptics {
fn default() -> Self {
Self::new()
}
}
// 8. Notification Feedback
/// Notification haptic patterns
pub struct NotificationHaptics {
manager: HapticManager,
}
impl NotificationHaptics {
pub fn new() -> Self {
NotificationHaptics {
manager: HapticManager::new(),
}
}
/// Incoming message
pub fn message(&self) -> bool {
vibrate_double_tap()
}
/// Incoming call
pub fn call(&self) -> bool {
vibrate_pattern(&[200, 200, 200])
}
/// Calendar reminder
pub fn reminder(&self) -> bool {
self.manager.feedback(FeedbackType::Warning)
}
/// Download complete
pub fn download_complete(&self) -> bool {
self.manager.feedback(FeedbackType::Success)
}
/// Download failed
pub fn download_failed(&self) -> bool {
self.manager.feedback(FeedbackType::Error)
}
/// Battery low
pub fn battery_low(&self) -> bool {
vibrate_pattern(&[100, 200, 100, 200, 100, 200, 500])
}
}
impl Default for NotificationHaptics {
fn default() -> Self {
Self::new()
}
}
// 9. Accessibility Feedback
/// Accessibility haptic feedback
pub struct AccessibilityHaptics {
manager: HapticManager,
}
impl AccessibilityHaptics {
pub fn new() -> Self {
AccessibilityHaptics {
manager: HapticManager::new(),
}
}
/// Focus gained
pub fn focus_gained(&self) -> bool {
self.manager.tap(20)
}
/// Boundary reached
pub fn boundary(&self) -> bool {
self.manager.tap(40)
}
/// Error occurred
pub fn error(&self) -> bool {
self.manager.feedback(FeedbackType::Error)
}
/// Success feedback
pub fn success(&self) -> bool {
self.manager.feedback(FeedbackType::Success)
}
/// Warning feedback
pub fn warning(&self) -> bool {
self.manager.feedback(FeedbackType::Warning)
}
}
impl Default for AccessibilityHaptics {
fn default() -> Self {
Self::new()
}
}
// 10. Vibration Utilities
/// Check if vibration is supported
pub fn is_vibration_supported() -> bool {
// In WASM: 'vibrate' in navigator
true // Simulated
}
/// Continuous vibration (until stopped)
pub fn vibrate_continuous() -> bool {
// Long vibration that should be stopped manually
vibrate_pattern(&[10000])
}
/// Morse code vibration
pub fn vibrate_morse_code(message: &str) -> bool {
let mut pattern = Vec::new();
let unit = 100; // Base time unit in ms
for ch in message.to_uppercase().chars() {
match ch {
'.' => pattern.extend_from_slice(&[unit, unit]),
'-' => pattern.extend_from_slice(&[3 * unit, unit]),
' ' => pattern.push(3 * unit), // Letter space
'/' => pattern.push(7 * unit), // Word space
_ => {},
}
}
vibrate_pattern(&pattern)
}
// Usage Examples
fn main() {
println!("=== Web Rust Haptic Feedback Examples ===\n");
// 1. Basic vibration
println!("--- 1. Basic Vibration ---");
vibrate(200);
println!("Short vibration: 200ms");
std::thread::sleep(std::time::Duration::from_millis(300));
// 2. Patterns
println!("
--- 2. Vibration Patterns ---");
vibrate_pattern(&[100, 50, 200, 50, 300]);
println!("Pattern: 100ms, pause, 200ms, pause, 300ms");
// 3. Common patterns
println!("
--- 3. Common Patterns ---");
println!("Success:");
vibrate_success();
std::thread::sleep(std::time::Duration::from_millis(500));
println!("Error:");
vibrate_error();
std::thread::sleep(std::time::Duration::from_millis(500));
println!("Warning:");
vibrate_warning();
// 4. Feedback types
println!("
--- 4. Feedback Types ---");
for feedback in [
FeedbackType::LightTap,
FeedbackType::MediumTap,
FeedbackType::HeavyTap,
FeedbackType::Success,
] {
println!("{:?}:", feedback);
feedback.execute();
std::thread::sleep(std::time::Duration::from_millis(300));
}
// 5. Haptic manager
println!("
--- 5. Haptic Manager ---");
let mut manager = HapticManager::new();
manager.set_intensity(0.5);
println!("Intensity set to 50%");
manager.feedback(FeedbackType::Confirm);
// 6. Advanced patterns
println!("
--- 6. Advanced Patterns ---");
println!("Heartbeat:");
vibrate_heartbeat(2);
std::thread::sleep(std::time::Duration::from_millis(1000));
println!("Rising:");
vibrate_rising();
std::thread::sleep(std::time::Duration::from_millis(1000));
println!("SOS:");
vibrate_sos();
// 7. UI feedback
println!("
--- 7. UI Feedback ---");
let ui = UIFeedback::new();
ui.button_press();
std::thread::sleep(std::time::Duration::from_millis(200));
ui.toggle_on();
std::thread::sleep(std::time::Duration::from_millis(200));
ui.confirm();
// 8. Gaming feedback
println!("
--- 8. Gaming Feedback ---");
let game = GameHaptics::new();
game.button_tap();
std::thread::sleep(std::time::Duration::from_millis(200));
game.impact(50);
std::thread::sleep(std::time::Duration::from_millis(200));
game.achievement();
// 9. Notification feedback
println!("
--- 9. Notification Feedback ---");
let notif = NotificationHaptics::new();
notif.message();
std::thread::sleep(std::time::Duration::from_millis(500));
notif.call();
// 10. Morse code
println!("
--- 10. Morse Code ---");
println!("SOS in morse code:");
vibrate_morse_code("... --- ...");
println!("
=== IMPORTANT NOTE ===");
println!("Vibration API is not available in all browsers and platforms.");
println!("Desktop browsers typically don't support vibration.");
println!("Mobile browsers (especially Android) have better support.");
println!("iOS Safari has limited or no vibration support.");
println!("");
println!("In WASM, actual implementation requires JavaScript interop.");
println!("Example: navigator.vibrate([200, 100, 200]);");
println!("
=== All Haptic Feedback Examples Completed ===");
}
💻 Estado de Red rust
🟡 intermediate
⭐⭐⭐
Verificar el estado y tipo de conexión de red usando APIs del navegador
⏱️ 25 min
🏷️ rust, web, mobile features
Prerequisites:
Intermediate Rust, Understanding of Web APIs
// Web Rust Network Status Examples
// Network status monitoring using browser Web APIs
//
// This demonstrates network status detection that would work in WebAssembly (WASM) context
//
// In WASM, you would use JavaScript interop with:
// - navigator.onLine
// - window.addEventListener('online')
// - window.addEventListener('offline')
// - navigator.connection (Network Information API)
use std::time::{SystemTime, UNIX_EPOCH};
// 1. Network Status Types
/// Connection state
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ConnectionState {
Online,
Offline,
Unknown,
}
/// Connection type
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ConnectionType {
Wifi,
Cellular,
Ethernet,
Bluetooth,
None,
Other,
Unknown,
}
/// Effective connection type (speed)
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EffectiveConnectionType {
Slow2G,
TwoG,
ThreeG,
FourG,
Unknown,
}
// 2. Network Status Information
/// Current network status
#[derive(Debug, Clone)]
pub struct NetworkStatus {
pub state: ConnectionState,
pub connection_type: ConnectionType,
pub effective_type: EffectiveConnectionType,
pub downlink: f64, // Mbps
pub rtt: u32, // Round-trip time in ms
pub save_data: bool, // Data saver mode
pub last_updated: u64, // Timestamp
}
impl NetworkStatus {
pub fn new() -> Self {
NetworkStatus {
state: ConnectionState::Online,
connection_type: ConnectionType::Unknown,
effective_type: EffectiveConnectionType::Unknown,
downlink: 0.0,
rtt: 0,
save_data: false,
last_updated: current_timestamp(),
}
}
pub fn is_online(&self) -> bool {
self.state == ConnectionState::Online
}
pub fn is_slow(&self) -> bool {
matches!(
self.effective_type,
EffectiveConnectionType::Slow2G | EffectiveConnectionType::TwoG
)
}
pub fn is_metered(&self) -> bool {
matches!(
self.connection_type,
ConnectionType::Cellular
)
}
}
fn current_timestamp() -> u64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs()
}
// 3. Network Monitor
/// Network event types
#[derive(Debug, Clone)]
pub enum NetworkEvent {
Online,
Offline,
ConnectionChange(ConnectionType),
SpeedChange(EffectiveConnectionType),
}
/// Network event handler
pub type NetworkEventHandler = Box<dyn Fn(NetworkEvent) + Send>;
/// Network monitor (simplified for demonstration)
pub struct NetworkMonitor {
status: NetworkStatus,
handlers: Vec<NetworkEventHandler>,
}
impl NetworkMonitor {
pub fn new() -> Self {
NetworkMonitor {
status: NetworkStatus::new(),
handlers: Vec::new(),
}
}
/// Register event handler
pub fn on_event<F>(&mut self, handler: F)
where
F: Fn(NetworkEvent) + Send + 'static,
{
self.handlers.push(Box::new(handler));
}
/// Update network status
pub fn update_status(&mut self, new_status: NetworkStatus) {
let old_state = self.status.state;
let old_type = self.status.connection_type;
let old_speed = self.status.effective_type;
self.status = new_status;
// Trigger events
if old_state != new_status.state {
let event = match new_status.state {
ConnectionState::Online => NetworkEvent::Online,
ConnectionState::Offline => NetworkEvent::Offline,
_ => return,
};
self.notify(event);
}
if old_type != new_status.connection_type {
self.notify(NetworkEvent::ConnectionChange(new_status.connection_type));
}
if old_speed != new_status.effective_type {
self.notify(NetworkEvent::SpeedChange(new_status.effective_type));
}
}
/// Get current status
pub fn status(&self) -> &NetworkStatus {
&self.status
}
/// Check if online
pub fn is_online(&self) -> bool {
self.status.is_online()
}
/// Notify all handlers
fn notify(&self, event: NetworkEvent) {
for handler in &self.handlers {
handler(event.clone());
}
}
}
impl Default for NetworkMonitor {
fn default() -> Self {
Self::new()
}
}
// 4. Connection Quality
/// Connection quality assessment
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ConnectionQuality {
Excellent,
Good,
Fair,
Poor,
}
impl ConnectionQuality {
pub fn from_status(status: &NetworkStatus) -> Self {
match (status.effective_type, status.downlink, status.rtt) {
(EffectiveConnectionType::FourG, dl, rtt) if dl >= 10.0 && rtt < 100 => {
ConnectionQuality::Excellent
},
(EffectiveConnectionType::FourG, _, _) |
(EffectiveConnectionType::ThreeG, dl, _) if dl >= 5.0 => {
ConnectionQuality::Good
},
(EffectiveConnectionType::ThreeG, _, _) => ConnectionQuality::Fair,
_ => ConnectionQuality::Poor,
}
}
pub fn is_good_for_video(&self) -> bool {
matches!(self, ConnectionQuality::Excellent | ConnectionQuality::Good)
}
pub fn is_good_for_audio(&self) -> bool {
!matches!(self, ConnectionQuality::Poor)
}
}
// 5. Adaptive Loading
/// Resource loading strategy based on network
#[derive(Debug, Clone)]
pub enum LoadingStrategy {
HighQuality, // Load full resources
Balanced, // Load optimized resources
DataSaver, // Load minimal resources
}
impl LoadingStrategy {
pub fn from_status(status: &NetworkStatus) -> Self {
if status.save_data || status.is_metered() {
LoadingStrategy::DataSaver
} else if status.is_slow() {
LoadingStrategy::Balanced
} else {
LoadingStrategy::HighQuality
}
}
}
// 6. Request Optimization
/// Optimize requests based on network
#[derive(Debug, Clone)]
pub struct RequestConfig {
pub timeout: u32, // milliseconds
pub retry_count: u32,
pub use_compression: bool,
pub batch_size: usize,
}
impl RequestConfig {
pub fn from_status(status: &NetworkStatus) -> Self {
let quality = ConnectionQuality::from_status(status);
match quality {
ConnectionQuality::Excellent => RequestConfig {
timeout: 5000,
retry_count: 3,
use_compression: false,
batch_size: 100,
},
ConnectionQuality::Good => RequestConfig {
timeout: 10000,
retry_count: 2,
use_compression: true,
batch_size: 50,
},
ConnectionQuality::Fair => RequestConfig {
timeout: 15000,
retry_count: 2,
use_compression: true,
batch_size: 25,
},
ConnectionQuality::Poor => RequestConfig {
timeout: 30000,
retry_count: 1,
use_compression: true,
batch_size: 10,
},
}
}
}
// 7. Offline Detection
/// Check if currently offline
pub fn is_offline() -> bool {
// In WASM: !navigator.onLine
false // Simulated
}
/// Check if currently online
pub fn is_online() -> bool {
// In WASM: navigator.onLine
true // Simulated
}
// 8. Bandwidth Estimation
/// Estimate available bandwidth
pub fn estimate_bandwidth(downlink: f64, rtt: u32) -> f64 {
// Rough estimation in Mbps
if rtt == 0 {
return downlink;
}
// Consider latency
let latency_factor = 1000.0 / (rtt as f64);
downlink * latency_factor.min(1.0)
}
/// Calculate optimal chunk size for file uploads
pub fn calculate_upload_chunk_size(status: &NetworkStatus) -> usize {
match status.effective_type {
EffectiveConnectionType::Slow2G => 32 * 1024, // 32 KB
EffectiveConnectionType::TwoG => 64 * 1024, // 64 KB
EffectiveConnectionType::ThreeG => 256 * 1024, // 256 KB
EffectiveConnectionType::FourG => 1024 * 1024, // 1 MB
EffectiveConnectionType::Unknown => 512 * 1024, // 512 KB
}
}
// 9. Retry Strategy
/// Retry strategy based on network
#[derive(Debug, Clone)]
pub struct RetryStrategy {
pub max_attempts: u32,
pub base_delay_ms: u32,
pub max_delay_ms: u32,
pub exponential_backoff: bool,
}
impl RetryStrategy {
pub fn from_status(status: &NetworkStatus) -> Self {
if status.is_slow() {
RetryStrategy {
max_attempts: 5,
base_delay_ms: 1000,
max_delay_ms: 10000,
exponential_backoff: true,
}
} else {
RetryStrategy {
max_attempts: 3,
base_delay_ms: 500,
max_delay_ms: 5000,
exponential_backoff: true,
}
}
}
pub fn calculate_delay(&self, attempt: u32) -> u32 {
if self.exponential_backoff {
let delay = self.base_delay_ms * 2_u32.pow(attempt.min(5));
delay.min(self.max_delay_ms)
} else {
self.base_delay_ms
}
}
}
// 10. Network Utilities
/// Check if should use offline mode
pub fn should_use_offline_mode(status: &NetworkStatus) -> bool {
!status.is_online() || status.is_slow() || status.save_data
}
/// Get recommended image quality based on network
pub fn get_image_quality(status: &NetworkStatus) -> u8 {
match ConnectionQuality::from_status(status) {
ConnectionQuality::Excellent => 100,
ConnectionQuality::Good => 85,
ConnectionQuality::Fair => 70,
ConnectionQuality::Poor => 50,
}
}
/// Calculate if should preload resources
pub fn should_preload(status: &NetworkStatus) -> bool {
status.is_online() && !status.save_data && !status.is_metered()
}
// Usage Examples
fn main() {
println!("=== Web Rust Network Status Examples ===\n");
// 1. Basic status check
println!("--- 1. Basic Status ---");
println!("Is online: {}", is_online());
println!("Is offline: {}", is_offline());
// 2. Create network monitor
println!("
--- 2. Network Monitor ---");
let mut monitor = NetworkMonitor::new();
// Add event handler
monitor.on_event(|event| {
println!("Network event: {:?}", event);
});
// Update status
let new_status = NetworkStatus {
state: ConnectionState::Online,
connection_type: ConnectionType::Wifi,
effective_type: EffectiveConnectionType::FourG,
downlink: 50.0,
rtt: 20,
save_data: false,
last_updated: current_timestamp(),
};
monitor.update_status(new_status);
println!("Current status: {:?}", monitor.status());
// 3. Connection quality
println!("
--- 3. Connection Quality ---");
let status = monitor.status();
let quality = ConnectionQuality::from_status(status);
println!("Quality: {:?}", quality);
println!("Good for video: {}", quality.is_good_for_video());
println!("Good for audio: {}", quality.is_good_for_audio());
// 4. Loading strategy
println!("
--- 4. Loading Strategy ---");
let strategy = LoadingStrategy::from_status(status);
println!("Strategy: {:?}", strategy);
// 5. Request config
println!("
--- 5. Request Configuration ---");
let config = RequestConfig::from_status(status);
println!("Timeout: {}ms", config.timeout);
println!("Retry count: {}", config.retry_count);
println!("Use compression: {}", config.use_compression);
println!("Batch size: {}", config.batch_size);
// 6. Bandwidth estimation
println!("
--- 6. Bandwidth ---");
let bandwidth = estimate_bandwidth(status.downlink, status.rtt);
println!("Estimated bandwidth: {:.2} Mbps", bandwidth);
// 7. Upload chunk size
println!("
--- 7. Upload Optimization ---");
let chunk_size = calculate_upload_chunk_size(status);
println!("Chunk size: {} bytes", chunk_size);
// 8. Retry strategy
println!("
--- 8. Retry Strategy ---");
let retry = RetryStrategy::from_status(status);
println!("Max attempts: {}", retry.max_attempts);
println!("Base delay: {}ms", retry.base_delay_ms);
for i in 0..retry.max_attempts {
println!("Attempt {} delay: {}ms", i + 1, retry.calculate_delay(i));
}
// 9. Image quality
println!("
--- 9. Image Optimization ---");
let quality = get_image_quality(status);
println!("Recommended image quality: {}%", quality);
// 10. Offline mode
println!("
--- 10. Offline Detection ---");
println!("Should use offline mode: {}", should_use_offline_mode(status));
println!("Should preload: {}", should_preload(status));
// 11. Different connection types
println!("
--- 11. Connection Types ---");
let types = [
(ConnectionType::Wifi, EffectiveConnectionType::FourG, 100.0, 10),
(ConnectionType::Cellular, EffectiveConnectionType::ThreeG, 5.0, 150),
(ConnectionType::Cellular, EffectiveConnectionType::TwoG, 0.5, 500),
];
for (conn_type, eff_type, dl, rtt) in types {
let test_status = NetworkStatus {
state: ConnectionState::Online,
connection_type: conn_type,
effective_type: eff_type,
downlink: dl,
rtt,
save_data: false,
last_updated: current_timestamp(),
};
println!("
{:?} - {:?}:", conn_type, eff_type);
println!(" Quality: {:?}", ConnectionQuality::from_status(&test_status));
println!(" Image quality: {}%", get_image_quality(&test_status));
println!(" Chunk size: {} bytes", calculate_upload_chunk_size(&test_status));
}
println!("
=== Note ===");
println!("Network Information API is experimental and not available in all browsers.");
println!("Actual implementation requires JavaScript interop in WASM.");
println!("
=== All Network Status Examples Completed ===");
}