Skip to main content

browser_protocol/autofill/
mod.rs

1//! Defines commands and events for Autofill.
2
3
4use serde::{Serialize, Deserialize};
5use serde_json::Value as JsonValue;
6use std::borrow::Cow;
7
8
9#[derive(Debug, Clone, Serialize, Deserialize, Default)]
10#[serde(rename_all = "camelCase")]
11pub struct CreditCard<'a> {
12    /// 16-digit credit card number.
13    number: Cow<'a, str>,
14    /// Name of the credit card owner.
15    name: Cow<'a, str>,
16    /// 2-digit expiry month.
17    expiryMonth: Cow<'a, str>,
18    /// 4-digit expiry year.
19    expiryYear: Cow<'a, str>,
20    /// 3-digit card verification code.
21    cvc: Cow<'a, str>,
22}
23
24impl<'a> CreditCard<'a> {
25    pub fn builder(number: impl Into<Cow<'a, str>>, name: impl Into<Cow<'a, str>>, expiryMonth: impl Into<Cow<'a, str>>, expiryYear: impl Into<Cow<'a, str>>, cvc: impl Into<Cow<'a, str>>) -> CreditCardBuilder<'a> {
26        CreditCardBuilder {
27            number: number.into(),
28            name: name.into(),
29            expiryMonth: expiryMonth.into(),
30            expiryYear: expiryYear.into(),
31            cvc: cvc.into(),
32        }
33    }
34    pub fn number(&self) -> &str { self.number.as_ref() }
35    pub fn name(&self) -> &str { self.name.as_ref() }
36    pub fn expiryMonth(&self) -> &str { self.expiryMonth.as_ref() }
37    pub fn expiryYear(&self) -> &str { self.expiryYear.as_ref() }
38    pub fn cvc(&self) -> &str { self.cvc.as_ref() }
39}
40
41
42pub struct CreditCardBuilder<'a> {
43    number: Cow<'a, str>,
44    name: Cow<'a, str>,
45    expiryMonth: Cow<'a, str>,
46    expiryYear: Cow<'a, str>,
47    cvc: Cow<'a, str>,
48}
49
50impl<'a> CreditCardBuilder<'a> {
51    pub fn build(self) -> CreditCard<'a> {
52        CreditCard {
53            number: self.number,
54            name: self.name,
55            expiryMonth: self.expiryMonth,
56            expiryYear: self.expiryYear,
57            cvc: self.cvc,
58        }
59    }
60}
61
62
63#[derive(Debug, Clone, Serialize, Deserialize, Default)]
64#[serde(rename_all = "camelCase")]
65pub struct AddressField<'a> {
66    /// address field name, for example GIVEN_NAME.
67    /// The full list of supported field names:
68    /// https://source.chromium.org/chromium/chromium/src/+/main:components/autofill/core/browser/field_types.cc;l=38
69    name: Cow<'a, str>,
70    /// address field value, for example Jon Doe.
71    value: Cow<'a, str>,
72}
73
74impl<'a> AddressField<'a> {
75    pub fn builder(name: impl Into<Cow<'a, str>>, value: impl Into<Cow<'a, str>>) -> AddressFieldBuilder<'a> {
76        AddressFieldBuilder {
77            name: name.into(),
78            value: value.into(),
79        }
80    }
81    pub fn name(&self) -> &str { self.name.as_ref() }
82    pub fn value(&self) -> &str { self.value.as_ref() }
83}
84
85
86pub struct AddressFieldBuilder<'a> {
87    name: Cow<'a, str>,
88    value: Cow<'a, str>,
89}
90
91impl<'a> AddressFieldBuilder<'a> {
92    pub fn build(self) -> AddressField<'a> {
93        AddressField {
94            name: self.name,
95            value: self.value,
96        }
97    }
98}
99
100/// A list of address fields.
101
102#[derive(Debug, Clone, Serialize, Deserialize, Default)]
103#[serde(rename_all = "camelCase")]
104pub struct AddressFields<'a> {
105    fields: Vec<AddressField<'a>>,
106}
107
108impl<'a> AddressFields<'a> {
109    pub fn builder(fields: Vec<AddressField<'a>>) -> AddressFieldsBuilder<'a> {
110        AddressFieldsBuilder {
111            fields: fields,
112        }
113    }
114    pub fn fields(&self) -> &[AddressField<'a>] { &self.fields }
115}
116
117
118pub struct AddressFieldsBuilder<'a> {
119    fields: Vec<AddressField<'a>>,
120}
121
122impl<'a> AddressFieldsBuilder<'a> {
123    pub fn build(self) -> AddressFields<'a> {
124        AddressFields {
125            fields: self.fields,
126        }
127    }
128}
129
130
131#[derive(Debug, Clone, Serialize, Deserialize, Default)]
132#[serde(rename_all = "camelCase")]
133pub struct Address<'a> {
134    /// fields and values defining an address.
135    fields: Vec<AddressField<'a>>,
136}
137
138impl<'a> Address<'a> {
139    pub fn builder(fields: Vec<AddressField<'a>>) -> AddressBuilder<'a> {
140        AddressBuilder {
141            fields: fields,
142        }
143    }
144    pub fn fields(&self) -> &[AddressField<'a>] { &self.fields }
145}
146
147
148pub struct AddressBuilder<'a> {
149    fields: Vec<AddressField<'a>>,
150}
151
152impl<'a> AddressBuilder<'a> {
153    pub fn build(self) -> Address<'a> {
154        Address {
155            fields: self.fields,
156        }
157    }
158}
159
160/// Defines how an address can be displayed like in chrome://settings/addresses.
161/// Address UI is a two dimensional array, each inner array is an "address information line", and when rendered in a UI surface should be displayed as such.
162/// The following address UI for instance:
163/// [[{name: "GIVE_NAME", value: "Jon"}, {name: "FAMILY_NAME", value: "Doe"}], [{name: "CITY", value: "Munich"}, {name: "ZIP", value: "81456"}]]
164/// should allow the receiver to render:
165/// Jon Doe
166/// Munich 81456
167
168#[derive(Debug, Clone, Serialize, Deserialize, Default)]
169#[serde(rename_all = "camelCase")]
170pub struct AddressUI<'a> {
171    /// A two dimension array containing the representation of values from an address profile.
172    addressFields: Vec<AddressFields<'a>>,
173}
174
175impl<'a> AddressUI<'a> {
176    pub fn builder(addressFields: Vec<AddressFields<'a>>) -> AddressUIBuilder<'a> {
177        AddressUIBuilder {
178            addressFields: addressFields,
179        }
180    }
181    pub fn addressFields(&self) -> &[AddressFields<'a>] { &self.addressFields }
182}
183
184
185pub struct AddressUIBuilder<'a> {
186    addressFields: Vec<AddressFields<'a>>,
187}
188
189impl<'a> AddressUIBuilder<'a> {
190    pub fn build(self) -> AddressUI<'a> {
191        AddressUI {
192            addressFields: self.addressFields,
193        }
194    }
195}
196
197/// Specified whether a filled field was done so by using the html autocomplete attribute or autofill heuristics.
198
199#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
200pub enum FillingStrategy {
201    #[default]
202    #[serde(rename = "autocompleteAttribute")]
203    AutocompleteAttribute,
204    #[serde(rename = "autofillInferred")]
205    AutofillInferred,
206}
207
208
209#[derive(Debug, Clone, Serialize, Deserialize, Default)]
210#[serde(rename_all = "camelCase")]
211pub struct FilledField<'a> {
212    /// The type of the field, e.g text, password etc.
213    htmlType: Cow<'a, str>,
214    /// the html id
215    id: Cow<'a, str>,
216    /// the html name
217    name: Cow<'a, str>,
218    /// the field value
219    value: Cow<'a, str>,
220    /// The actual field type, e.g FAMILY_NAME
221    autofillType: Cow<'a, str>,
222    /// The filling strategy
223    fillingStrategy: FillingStrategy,
224    /// The frame the field belongs to
225    frameId: crate::page::FrameId<'a>,
226    /// The form field's DOM node
227    fieldId: crate::dom::BackendNodeId,
228}
229
230impl<'a> FilledField<'a> {
231    pub fn builder(htmlType: impl Into<Cow<'a, str>>, id: impl Into<Cow<'a, str>>, name: impl Into<Cow<'a, str>>, value: impl Into<Cow<'a, str>>, autofillType: impl Into<Cow<'a, str>>, fillingStrategy: FillingStrategy, frameId: crate::page::FrameId<'a>, fieldId: crate::dom::BackendNodeId) -> FilledFieldBuilder<'a> {
232        FilledFieldBuilder {
233            htmlType: htmlType.into(),
234            id: id.into(),
235            name: name.into(),
236            value: value.into(),
237            autofillType: autofillType.into(),
238            fillingStrategy: fillingStrategy,
239            frameId: frameId,
240            fieldId: fieldId,
241        }
242    }
243    pub fn htmlType(&self) -> &str { self.htmlType.as_ref() }
244    pub fn id(&self) -> &str { self.id.as_ref() }
245    pub fn name(&self) -> &str { self.name.as_ref() }
246    pub fn value(&self) -> &str { self.value.as_ref() }
247    pub fn autofillType(&self) -> &str { self.autofillType.as_ref() }
248    pub fn fillingStrategy(&self) -> &FillingStrategy { &self.fillingStrategy }
249    pub fn frameId(&self) -> &crate::page::FrameId<'a> { &self.frameId }
250    pub fn fieldId(&self) -> &crate::dom::BackendNodeId { &self.fieldId }
251}
252
253
254pub struct FilledFieldBuilder<'a> {
255    htmlType: Cow<'a, str>,
256    id: Cow<'a, str>,
257    name: Cow<'a, str>,
258    value: Cow<'a, str>,
259    autofillType: Cow<'a, str>,
260    fillingStrategy: FillingStrategy,
261    frameId: crate::page::FrameId<'a>,
262    fieldId: crate::dom::BackendNodeId,
263}
264
265impl<'a> FilledFieldBuilder<'a> {
266    pub fn build(self) -> FilledField<'a> {
267        FilledField {
268            htmlType: self.htmlType,
269            id: self.id,
270            name: self.name,
271            value: self.value,
272            autofillType: self.autofillType,
273            fillingStrategy: self.fillingStrategy,
274            frameId: self.frameId,
275            fieldId: self.fieldId,
276        }
277    }
278}
279
280/// Trigger autofill on a form identified by the fieldId.
281/// If the field and related form cannot be autofilled, returns an error.
282
283#[derive(Debug, Clone, Serialize, Deserialize, Default)]
284#[serde(rename_all = "camelCase")]
285pub struct TriggerParams<'a> {
286    /// Identifies a field that serves as an anchor for autofill.
287    fieldId: crate::dom::BackendNodeId,
288    /// Identifies the frame that field belongs to.
289    #[serde(skip_serializing_if = "Option::is_none")]
290    frameId: Option<crate::page::FrameId<'a>>,
291    /// Credit card information to fill out the form. Credit card data is not saved.  Mutually exclusive with 'address'.
292    #[serde(skip_serializing_if = "Option::is_none")]
293    card: Option<CreditCard<'a>>,
294    /// Address to fill out the form. Address data is not saved. Mutually exclusive with 'card'.
295    #[serde(skip_serializing_if = "Option::is_none")]
296    address: Option<Address<'a>>,
297}
298
299impl<'a> TriggerParams<'a> {
300    pub fn builder(fieldId: crate::dom::BackendNodeId) -> TriggerParamsBuilder<'a> {
301        TriggerParamsBuilder {
302            fieldId: fieldId,
303            frameId: None,
304            card: None,
305            address: None,
306        }
307    }
308    pub fn fieldId(&self) -> &crate::dom::BackendNodeId { &self.fieldId }
309    pub fn frameId(&self) -> Option<&crate::page::FrameId<'a>> { self.frameId.as_ref() }
310    pub fn card(&self) -> Option<&CreditCard<'a>> { self.card.as_ref() }
311    pub fn address(&self) -> Option<&Address<'a>> { self.address.as_ref() }
312}
313
314
315pub struct TriggerParamsBuilder<'a> {
316    fieldId: crate::dom::BackendNodeId,
317    frameId: Option<crate::page::FrameId<'a>>,
318    card: Option<CreditCard<'a>>,
319    address: Option<Address<'a>>,
320}
321
322impl<'a> TriggerParamsBuilder<'a> {
323    /// Identifies the frame that field belongs to.
324    pub fn frameId(mut self, frameId: crate::page::FrameId<'a>) -> Self { self.frameId = Some(frameId); self }
325    /// Credit card information to fill out the form. Credit card data is not saved.  Mutually exclusive with 'address'.
326    pub fn card(mut self, card: CreditCard<'a>) -> Self { self.card = Some(card); self }
327    /// Address to fill out the form. Address data is not saved. Mutually exclusive with 'card'.
328    pub fn address(mut self, address: Address<'a>) -> Self { self.address = Some(address); self }
329    pub fn build(self) -> TriggerParams<'a> {
330        TriggerParams {
331            fieldId: self.fieldId,
332            frameId: self.frameId,
333            card: self.card,
334            address: self.address,
335        }
336    }
337}
338
339impl<'a> TriggerParams<'a> { pub const METHOD: &'static str = "Autofill.trigger"; }
340
341impl<'a> crate::CdpCommand<'a> for TriggerParams<'a> {
342    const METHOD: &'static str = "Autofill.trigger";
343    type Response = crate::EmptyReturns;
344}
345
346/// Set addresses so that developers can verify their forms implementation.
347
348#[derive(Debug, Clone, Serialize, Deserialize, Default)]
349#[serde(rename_all = "camelCase")]
350pub struct SetAddressesParams<'a> {
351    addresses: Vec<Address<'a>>,
352}
353
354impl<'a> SetAddressesParams<'a> {
355    pub fn builder(addresses: Vec<Address<'a>>) -> SetAddressesParamsBuilder<'a> {
356        SetAddressesParamsBuilder {
357            addresses: addresses,
358        }
359    }
360    pub fn addresses(&self) -> &[Address<'a>] { &self.addresses }
361}
362
363
364pub struct SetAddressesParamsBuilder<'a> {
365    addresses: Vec<Address<'a>>,
366}
367
368impl<'a> SetAddressesParamsBuilder<'a> {
369    pub fn build(self) -> SetAddressesParams<'a> {
370        SetAddressesParams {
371            addresses: self.addresses,
372        }
373    }
374}
375
376impl<'a> SetAddressesParams<'a> { pub const METHOD: &'static str = "Autofill.setAddresses"; }
377
378impl<'a> crate::CdpCommand<'a> for SetAddressesParams<'a> {
379    const METHOD: &'static str = "Autofill.setAddresses";
380    type Response = crate::EmptyReturns;
381}
382
383#[derive(Debug, Clone, Serialize, Deserialize, Default)]
384pub struct DisableParams {}
385
386impl DisableParams { pub const METHOD: &'static str = "Autofill.disable"; }
387
388impl<'a> crate::CdpCommand<'a> for DisableParams {
389    const METHOD: &'static str = "Autofill.disable";
390    type Response = crate::EmptyReturns;
391}
392
393#[derive(Debug, Clone, Serialize, Deserialize, Default)]
394pub struct EnableParams {}
395
396impl EnableParams { pub const METHOD: &'static str = "Autofill.enable"; }
397
398impl<'a> crate::CdpCommand<'a> for EnableParams {
399    const METHOD: &'static str = "Autofill.enable";
400    type Response = crate::EmptyReturns;
401}