data_for_seo/api/content_analysis/
mod.rs1use crate::entity::{
2 ContentAnalysisApiAvailableFilters, ContentAnalysisApiCategory,
3 ContentAnalysisApiCategoryTrends, ContentAnalysisApiIdList, ContentAnalysisApiLanguage,
4 ContentAnalysisApiLocation, ContentAnalysisApiPhraseTrends,
5 ContentAnalysisApiRatingDistribution, ContentAnalysisApiSearch,
6 ContentAnalysisApiSentimentAnalysis, ContentAnalysisApiSummary,
7};
8use crate::{DataForSeoApiResponse, DataForSeoClient};
9use serde::{Deserialize, Serialize};
10use serde_json::Value;
11use std::collections::HashMap;
12
13pub struct ContentAnalysisApi<'a> {
16 client: &'a DataForSeoClient,
17}
18
19impl DataForSeoClient {
20 pub fn content_analysis(&self) -> ContentAnalysisApi<'_> {
22 ContentAnalysisApi { client: self }
23 }
24}
25
26impl ContentAnalysisApi<'_> {
27 pub async fn search(
30 &self,
31 data: Vec<ContentAnalysisApiSearchPost>,
32 ) -> DataForSeoApiResponse<ContentAnalysisApiSearch> {
33 self.client
34 .http_post("/v3/content_analysis/search/live", &data)
35 .await
36 }
37
38 pub async fn summary(
41 &self,
42 data: Vec<ContentAnalysisApiSummaryPost>,
43 ) -> DataForSeoApiResponse<ContentAnalysisApiSummary> {
44 self.client
45 .http_post("/v3/content_analysis/summary/live", &data)
46 .await
47 }
48
49 pub async fn sentiment_analysis(
52 &self,
53 data: Vec<ContentAnalysisApiSentimentAnalysisPost>,
54 ) -> DataForSeoApiResponse<ContentAnalysisApiSentimentAnalysis> {
55 self.client
56 .http_post("/v3/content_analysis/sentiment_analysis/live", &data)
57 .await
58 }
59
60 pub async fn rating_distribution(
63 &self,
64 data: Vec<ContentAnalysisApiRatingDistributionPost>,
65 ) -> DataForSeoApiResponse<ContentAnalysisApiRatingDistribution> {
66 self.client
67 .http_post("/v3/content_analysis/rating_distribution/live", &data)
68 .await
69 }
70
71 pub async fn phrase_trends(
74 &self,
75 data: Vec<ContentAnalysisApiPhraseTrendsPost>,
76 ) -> DataForSeoApiResponse<ContentAnalysisApiPhraseTrends> {
77 self.client
78 .http_post("/v3/content_analysis/phrase_trends/live", &data)
79 .await
80 }
81
82 pub async fn category_trends(
85 &self,
86 data: Vec<ContentAnalysisApiCategoryTrendsPost>,
87 ) -> DataForSeoApiResponse<ContentAnalysisApiCategoryTrends> {
88 self.client
89 .http_post("/v3/content_analysis/category_trends/live", &data)
90 .await
91 }
92
93 pub async fn id_list(
96 &self,
97 data: Vec<ContentAnalysisApiIdListPost>,
98 ) -> DataForSeoApiResponse<ContentAnalysisApiIdList> {
99 self.client
100 .http_post("/v3/content_analysis/id_list", &data)
101 .await
102 }
103
104 pub async fn categories(&self) -> DataForSeoApiResponse<ContentAnalysisApiCategory> {
107 self.client
108 .http_get("/v3/content_analysis/categories")
109 .await
110 }
111
112 pub async fn locations(&self) -> DataForSeoApiResponse<ContentAnalysisApiLocation> {
115 self.client.http_get("/v3/content_analysis/locations").await
116 }
117
118 pub async fn languages(&self) -> DataForSeoApiResponse<ContentAnalysisApiLanguage> {
121 self.client.http_get("/v3/content_analysis/languages").await
122 }
123
124 pub async fn available_filters(
127 &self,
128 ) -> DataForSeoApiResponse<ContentAnalysisApiAvailableFilters> {
129 self.client
130 .http_get("/v3/content_analysis/available_filters")
131 .await
132 }
133}
134
135#[derive(Debug, Default, Serialize, Deserialize, Clone)]
137pub struct ContentAnalysisApiSearchPost {
138 pub keyword: String,
141 #[serde(skip_serializing_if = "Option::is_none")]
144 pub keyword_fields: Option<HashMap<String, String>>,
145 #[serde(skip_serializing_if = "Option::is_none")]
148 pub page_type: Option<Vec<String>>,
149 #[serde(skip_serializing_if = "Option::is_none")]
151 pub search_mode: Option<String>,
152 #[serde(skip_serializing_if = "Option::is_none")]
154 pub limit: Option<i32>,
155 #[serde(skip_serializing_if = "Option::is_none")]
157 pub filters: Option<Vec<Value>>,
158 #[serde(skip_serializing_if = "Option::is_none")]
160 pub order_by: Option<Vec<String>>,
161 #[serde(skip_serializing_if = "Option::is_none")]
163 pub offset: Option<i32>,
164 #[serde(skip_serializing_if = "Option::is_none")]
166 pub offset_token: Option<String>,
167 #[serde(skip_serializing_if = "Option::is_none")]
169 pub rank_scale: Option<String>,
170 #[serde(skip_serializing_if = "Option::is_none")]
172 pub tag: Option<String>,
173}
174
175impl ContentAnalysisApiSearchPost {
176 pub fn new(keyword: &str) -> ContentAnalysisApiSearchPost {
178 ContentAnalysisApiSearchPost {
179 keyword: keyword.to_string(),
180 ..Default::default()
181 }
182 }
183}
184
185#[derive(Debug, Default, Serialize, Deserialize, Clone)]
187pub struct ContentAnalysisApiSummaryPost {
188 pub keyword: String,
191 #[serde(skip_serializing_if = "Option::is_none")]
194 pub keyword_fields: Option<HashMap<String, String>>,
195 #[serde(skip_serializing_if = "Option::is_none")]
198 pub page_type: Option<Vec<String>>,
199 #[serde(skip_serializing_if = "Option::is_none")]
202 pub internal_list_limit: Option<i32>,
203 #[serde(skip_serializing_if = "Option::is_none")]
206 pub positive_connotation_threshold: Option<f64>,
207 #[serde(skip_serializing_if = "Option::is_none")]
210 pub sentiments_connotation_threshold: Option<f64>,
211 #[serde(skip_serializing_if = "Option::is_none")]
213 pub initial_dataset_filters: Option<Vec<Value>>,
214 #[serde(skip_serializing_if = "Option::is_none")]
216 pub rank_scale: Option<String>,
217 #[serde(skip_serializing_if = "Option::is_none")]
219 pub tag: Option<String>,
220}
221
222impl ContentAnalysisApiSummaryPost {
223 pub fn new(keyword: &str) -> ContentAnalysisApiSummaryPost {
225 ContentAnalysisApiSummaryPost {
226 keyword: keyword.to_string(),
227 ..Default::default()
228 }
229 }
230}
231
232#[derive(Debug, Default, Serialize, Deserialize, Clone)]
234pub struct ContentAnalysisApiSentimentAnalysisPost {
235 pub keyword: String,
238 #[serde(skip_serializing_if = "Option::is_none")]
241 pub keyword_fields: Option<HashMap<String, String>>,
242 #[serde(skip_serializing_if = "Option::is_none")]
245 pub page_type: Option<Vec<String>>,
246 #[serde(skip_serializing_if = "Option::is_none")]
249 pub internal_list_limit: Option<i32>,
250 #[serde(skip_serializing_if = "Option::is_none")]
253 pub positive_connotation_threshold: Option<f64>,
254 #[serde(skip_serializing_if = "Option::is_none")]
257 pub sentiments_connotation_threshold: Option<f64>,
258 #[serde(skip_serializing_if = "Option::is_none")]
260 pub initial_dataset_filters: Option<Vec<Value>>,
261 #[serde(skip_serializing_if = "Option::is_none")]
263 pub rank_scale: Option<String>,
264 #[serde(skip_serializing_if = "Option::is_none")]
266 pub tag: Option<String>,
267}
268
269impl ContentAnalysisApiSentimentAnalysisPost {
270 pub fn new(keyword: &str) -> ContentAnalysisApiSentimentAnalysisPost {
272 ContentAnalysisApiSentimentAnalysisPost {
273 keyword: keyword.to_string(),
274 ..Default::default()
275 }
276 }
277}
278
279#[derive(Debug, Default, Serialize, Deserialize, Clone)]
281pub struct ContentAnalysisApiRatingDistributionPost {
282 pub keyword: String,
285 #[serde(skip_serializing_if = "Option::is_none")]
288 pub keyword_fields: Option<HashMap<String, String>>,
289 #[serde(skip_serializing_if = "Option::is_none")]
292 pub page_type: Option<Vec<String>>,
293 #[serde(skip_serializing_if = "Option::is_none")]
296 pub internal_list_limit: Option<i32>,
297 #[serde(skip_serializing_if = "Option::is_none")]
299 pub search_mode: Option<String>,
300 #[serde(skip_serializing_if = "Option::is_none")]
303 pub positive_connotation_threshold: Option<f64>,
304 #[serde(skip_serializing_if = "Option::is_none")]
307 pub sentiments_connotation_threshold: Option<f64>,
308 #[serde(skip_serializing_if = "Option::is_none")]
310 pub initial_dataset_filters: Option<Vec<Value>>,
311 #[serde(skip_serializing_if = "Option::is_none")]
313 pub rank_scale: Option<String>,
314 #[serde(skip_serializing_if = "Option::is_none")]
316 pub tag: Option<String>,
317}
318
319impl ContentAnalysisApiRatingDistributionPost {
320 pub fn new(keyword: &str) -> ContentAnalysisApiRatingDistributionPost {
322 ContentAnalysisApiRatingDistributionPost {
323 keyword: keyword.to_string(),
324 ..Default::default()
325 }
326 }
327}
328
329#[derive(Debug, Default, Serialize, Deserialize, Clone)]
331pub struct ContentAnalysisApiPhraseTrendsPost {
332 pub keyword: String,
335 pub date_from: String,
337 #[serde(skip_serializing_if = "Option::is_none")]
339 pub date_to: Option<String>,
340 #[serde(skip_serializing_if = "Option::is_none")]
342 pub date_group: Option<String>,
343 #[serde(skip_serializing_if = "Option::is_none")]
346 pub keyword_fields: Option<HashMap<String, String>>,
347 #[serde(skip_serializing_if = "Option::is_none")]
350 pub page_type: Option<Vec<String>>,
351 #[serde(skip_serializing_if = "Option::is_none")]
353 pub search_mode: Option<String>,
354 #[serde(skip_serializing_if = "Option::is_none")]
357 pub internal_list_limit: Option<i32>,
358 #[serde(skip_serializing_if = "Option::is_none")]
360 pub initial_dataset_filters: Option<Vec<Value>>,
361 #[serde(skip_serializing_if = "Option::is_none")]
363 pub rank_scale: Option<String>,
364 #[serde(skip_serializing_if = "Option::is_none")]
366 pub tag: Option<String>,
367}
368
369impl ContentAnalysisApiPhraseTrendsPost {
370 pub fn new(keyword: &str, date_from: &str) -> ContentAnalysisApiPhraseTrendsPost {
372 ContentAnalysisApiPhraseTrendsPost {
373 keyword: keyword.to_string(),
374 date_from: date_from.to_string(),
375 ..Default::default()
376 }
377 }
378}
379
380#[derive(Debug, Default, Serialize, Deserialize, Clone)]
382pub struct ContentAnalysisApiCategoryTrendsPost {
383 pub category_code: i64,
385 pub date_from: String,
387 #[serde(skip_serializing_if = "Option::is_none")]
389 pub date_to: Option<String>,
390 #[serde(skip_serializing_if = "Option::is_none")]
392 pub date_group: Option<String>,
393 #[serde(skip_serializing_if = "Option::is_none")]
396 pub page_type: Option<Vec<String>>,
397 #[serde(skip_serializing_if = "Option::is_none")]
399 pub search_mode: Option<String>,
400 #[serde(skip_serializing_if = "Option::is_none")]
403 pub internal_list_limit: Option<i32>,
404 #[serde(skip_serializing_if = "Option::is_none")]
406 pub initial_dataset_filters: Option<Vec<Value>>,
407 #[serde(skip_serializing_if = "Option::is_none")]
409 pub rank_scale: Option<String>,
410 #[serde(skip_serializing_if = "Option::is_none")]
412 pub tag: Option<String>,
413}
414
415impl ContentAnalysisApiCategoryTrendsPost {
416 pub fn new(category_code: i64, date_from: &str) -> ContentAnalysisApiCategoryTrendsPost {
418 ContentAnalysisApiCategoryTrendsPost {
419 category_code,
420 date_from: date_from.to_string(),
421 ..Default::default()
422 }
423 }
424}
425
426#[derive(Debug, Default, Serialize, Deserialize, Clone)]
428pub struct ContentAnalysisApiIdListPost {
429 pub datetime_from: String,
431 pub datetime_to: String,
433 #[serde(skip_serializing_if = "Option::is_none")]
435 pub limit: Option<i32>,
436 #[serde(skip_serializing_if = "Option::is_none")]
438 pub offset: Option<i32>,
439 #[serde(skip_serializing_if = "Option::is_none")]
441 pub sort: Option<String>,
442 #[serde(skip_serializing_if = "Option::is_none")]
444 pub include_metadata: Option<bool>,
445}
446
447impl ContentAnalysisApiIdListPost {
448 pub fn new(datetime_from: &str, datetime_to: &str) -> ContentAnalysisApiIdListPost {
451 ContentAnalysisApiIdListPost {
452 datetime_from: datetime_from.to_string(),
453 datetime_to: datetime_to.to_string(),
454 ..Default::default()
455 }
456 }
457}