Skip to main content

car_integrations/contacts/
mod.rs

1//! Contacts capability — enumerate containers, query contacts.
2
3use serde::{Deserialize, Serialize};
4
5use super::{Availability, IntegrationError};
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct Container {
9    pub id: String,
10    pub name: String,
11    /// Source label (account / provider) when available.
12    pub source: Option<String>,
13}
14
15#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct Contact {
17    pub id: String,
18    pub container_id: Option<String>,
19    pub display_name: String,
20    #[serde(default)]
21    pub emails: Vec<String>,
22    #[serde(default)]
23    pub phone_numbers: Vec<String>,
24    pub organization: Option<String>,
25}
26
27#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct ContainerListing {
29    #[serde(flatten)]
30    pub availability: Availability,
31    pub containers: Vec<Container>,
32}
33
34#[derive(Debug, Clone, Serialize, Deserialize)]
35pub struct ContactListing {
36    #[serde(flatten)]
37    pub availability: Availability,
38    pub contacts: Vec<Contact>,
39    /// Total match count, which may be larger than `contacts.len()` when
40    /// the backend paginates.
41    pub total: usize,
42}
43
44pub fn list_containers() -> Result<ContainerListing, IntegrationError> {
45    Ok(ContainerListing {
46        availability: current_backend_pending(),
47        containers: vec![],
48    })
49}
50
51/// Query contacts with a free-text `query` (name, email, phone substring).
52/// When `container_ids` is empty, searches all accessible containers.
53pub fn list_contacts(
54    _query: &str,
55    _container_ids: &[String],
56    _limit: usize,
57) -> Result<ContactListing, IntegrationError> {
58    Ok(ContactListing {
59        availability: current_backend_pending(),
60        contacts: vec![],
61        total: 0,
62    })
63}
64
65fn current_backend_pending() -> Availability {
66    #[cfg(target_os = "macos")]
67    {
68        Availability::pending(
69            "contacts_framework",
70            "Contacts.framework backend not yet wired. API shape is \
71             stable; downstream apps can code against it now.",
72        )
73    }
74    #[cfg(target_os = "windows")]
75    {
76        Availability::pending(
77            "windows_contacts",
78            "Windows Contacts API + MS Graph backends not yet wired. \
79             API shape is stable; downstream apps can code against it now.",
80        )
81    }
82    #[cfg(target_os = "linux")]
83    {
84        Availability::pending(
85            "eds",
86            "Evolution Data Server + CardDAV backends not yet wired. \
87             API shape is stable; downstream apps can code against it now.",
88        )
89    }
90    #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "linux")))]
91    {
92        Availability::pending("none", "Unsupported OS — no contacts backend modeled.")
93    }
94}