1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
//! Administrative operations for the Feature Service client.
use super::FeatureServiceClient;
use crate::{LayerId, Result};
use tracing::instrument;
impl<'a> FeatureServiceClient<'a> {
/// Deletes all features from a layer.
///
/// This operation removes all features from the specified layer while preserving
/// the layer structure and schema. Use with caution as this operation cannot be undone.
///
/// # Arguments
///
/// * `layer_id` - The layer to truncate
///
/// # Example
///
/// ```no_run
/// use arcgis::{ArcGISClient, ApiKeyAuth, FeatureServiceClient, LayerId};
///
/// # async fn example() -> arcgis::Result<()> {
/// let auth = ApiKeyAuth::new("YOUR_API_KEY");
/// let client = ArcGISClient::new(auth);
/// let service = FeatureServiceClient::new("https://example.com/FeatureServer", &client);
///
/// // Delete all features from layer 0
/// let result = service.truncate(LayerId::new(0)).await?;
/// println!("Truncate successful: {}", result.success());
/// # Ok(())
/// # }
/// ```
#[instrument(skip(self), fields(layer_id = %layer_id))]
pub async fn truncate(&self, layer_id: LayerId) -> Result<crate::TruncateResult> {
tracing::debug!("Truncating layer");
let url = format!("{}/{}/truncate", self.base_url, layer_id);
// Build form data
let mut form = vec![("f", "json")];
// Add token if required by auth provider
let token_value;
if let Some(token) = self.client.get_token_if_required().await? {
token_value = token;
form.push(("token", token_value.as_str()));
}
let response = self.client.http().post(&url).form(&form).send().await?;
let status = response.status();
if !status.is_success() {
let error_text = response
.text()
.await
.unwrap_or_else(|e| format!("Failed to read error: {}", e));
tracing::error!(status = %status, error = %error_text, "truncate request failed");
return Err(crate::Error::from(crate::ErrorKind::Api {
code: status.as_u16() as i32,
message: format!("HTTP {}: {}", status, error_text),
}));
}
let result: crate::TruncateResult = response.json().await?;
tracing::info!(success = result.success(), "Truncate completed");
Ok(result)
}
/// Queries domains and subtypes for a layer.
///
/// Returns coded value domains and subtype information for specified layers.
/// This is useful for getting valid values for fields with domains.
///
/// # Arguments
///
/// * `layers` - Layer IDs to query domains for. If empty, queries all layers.
///
/// # Example
///
/// ```no_run
/// use arcgis::{ArcGISClient, ApiKeyAuth, FeatureServiceClient, LayerId};
///
/// # async fn example() -> arcgis::Result<()> {
/// let auth = ApiKeyAuth::new("YOUR_API_KEY");
/// let client = ArcGISClient::new(auth);
/// let service = FeatureServiceClient::new("https://example.com/FeatureServer", &client);
///
/// // Query domains for specific layers
/// let result = service.query_domains(vec![LayerId::new(0), LayerId::new(1)]).await?;
/// # Ok(())
/// # }
/// ```
#[instrument(skip(self), fields(layer_count = layers.len()))]
pub async fn query_domains(&self, layers: Vec<LayerId>) -> Result<crate::QueryDomainsResponse> {
tracing::debug!("Querying domains");
let url = format!("{}/queryDomains", self.base_url);
let layers_str = layers
.iter()
.map(|id| id.to_string())
.collect::<Vec<_>>()
.join(",");
tracing::debug!(url = %url, layers = %layers_str, "Sending queryDomains request");
let mut form = vec![("f", "json")];
// Add token if required by auth provider
let token_opt = self.client.get_token_if_required().await?;
let token_str;
if let Some(token) = token_opt {
token_str = token;
form.push(("token", token_str.as_str()));
}
if !layers_str.is_empty() {
form.push(("layers", &layers_str));
}
let response = self.client.http().post(&url).form(&form).send().await?;
let status = response.status();
if !status.is_success() {
let error_text = response
.text()
.await
.unwrap_or_else(|e| format!("Failed to read error: {}", e));
tracing::error!(status = %status, error = %error_text, "queryDomains request failed");
return Err(crate::Error::from(crate::ErrorKind::Api {
code: status.as_u16() as i32,
message: format!("HTTP {}: {}", status, error_text),
}));
}
let result: crate::QueryDomainsResponse = response.json().await?;
tracing::info!(
layer_count = result.layers().len(),
"queryDomains completed"
);
Ok(result)
}
}