viceroy_lib/wiggle_abi/
device_detection_impl.rs1use crate::error::Error;
4use crate::wiggle_abi::{fastly_device_detection::FastlyDeviceDetection, FastlyStatus, Session};
5use std::convert::TryFrom;
6use wiggle::{GuestMemory, GuestPtr};
7
8#[derive(Debug, thiserror::Error)]
9pub enum DeviceDetectionError {
10 #[error("No device detection data: {0}")]
12 NoDeviceDetectionData(String),
13}
14
15impl DeviceDetectionError {
16 pub fn to_fastly_status(&self) -> FastlyStatus {
18 use DeviceDetectionError::*;
19 match self {
20 NoDeviceDetectionData(_) => FastlyStatus::None,
21 }
22 }
23}
24
25impl FastlyDeviceDetection for Session {
26 fn lookup(
27 &mut self,
28 memory: &mut GuestMemory<'_>,
29 user_agent: GuestPtr<str>,
30 buf: GuestPtr<u8>,
31 buf_len: u32,
32 nwritten_out: GuestPtr<u32>,
33 ) -> Result<(), Error> {
34 let result = {
35 let user_agent_slice = memory
36 .as_slice(user_agent.as_bytes())?
37 .ok_or(Error::SharedMemory)?;
38 let user_agent_str = std::str::from_utf8(&user_agent_slice)?;
39
40 self.device_detection_lookup(user_agent_str)
41 .ok_or_else(|| {
42 DeviceDetectionError::NoDeviceDetectionData(user_agent_str.to_string())
43 })?
44 };
45
46 if result.len() > buf_len as usize {
47 memory.write(nwritten_out, u32::try_from(result.len()).unwrap_or(0))?;
48 return Err(Error::BufferLengthError {
49 buf: "device_detection_lookup",
50 len: "device_detection_lookup_max_len",
51 });
52 }
53
54 let result_len =
55 u32::try_from(result.len()).expect("smaller than buf_len means it must fit");
56
57 memory.copy_from_slice(result.as_bytes(), buf.as_array(result_len))?;
58
59 memory.write(nwritten_out, result_len)?;
60 Ok(())
61 }
62}