Google Trends adapter — unofficial trends.google.com widget API, no auth token
| Tier | infrastructure |
| Role | unclassified (baselined) |
| Path | crates/infrastructure/adapters-google-trends |
| Edition | 2021 |
| Targets | infrastructure_adapters_google_trends |
| Public items | 0 across 0 modules |
| Tests | 17 |
What it is for
Google Trends adapter.
A SourceIngest implementor over trends.google.com's unofficial widget API (https://trends.google.com) — see src/client.rs's module doc for the fragility markers this carries (undocumented XSSI-prefixed JSON, no published stability guarantee) that a documented API like Places or Shodan does not have. No authentication of any kind: the source (plumber/src/collectors/google_trends.rs) and this port both rely only on looking like a browser, not on any credential — see src/config.rs's module doc for the evidence trail behind that claim.
Lifted from plumber/src/collectors/google_trends.rs (Gate 4.5 provenance, see CHANGELOG.md). Confirmed against the source directly: GoogleTrendsCollector is one of four sibling files in plumber/src/collectors/ that impl Collector for ... (renamed SourceIngest on this harvest, foundation-source-ingest) — so, unlike infrastructure-adapters-shodan, this crate depends on foundation-source-ingest and GoogleTrendsClient implements it.
# Example
# async fn example() {
use infrastructure_adapters_google_trends::{GoogleTrendsClient, GoogleTrendsConfig};
use foundation_source_ingest::SourceIngest;
let config = GoogleTrendsConfig::new(
vec"plumber near me".to_string(),
"US-AZ",
);
let client = GoogleTrendsClient::new(config).unwrap();
let result = client.ingest().await.unwrap();
println!("collected {} points, {} errors", result.items.len(), result.error_count);
# }
Capabilities
No public items.
How to use it
From this crate's own rustdoc:
# async fn example() {
use infrastructure_adapters_google_trends::{GoogleTrendsClient, GoogleTrendsConfig};
use foundation_source_ingest::SourceIngest;
let config = GoogleTrendsConfig::new(
vec!["plumber near me".to_string()],
"US-AZ",
);
let client = GoogleTrendsClient::new(config).unwrap();
let result = client.ingest().await.unwrap();
println!("collected {} points, {} errors", result.items.len(), result.error_count);
# }
Module structure
No public modules: the crate root is its whole surface.
Public surface
No public items.
Re-exports. Exported here, defined elsewhere.
| Export | Defined in |
|---|---|
GoogleTrendsClient | client::GoogleTrendsClient |
GoogleTrendsConfig | config::GoogleTrendsConfig |
TrendsError | error::TrendsError |
{RelatedQuery,TrendPoint} | types::{RelatedQuery,TrendPoint} |
Boundary
Reaches into foundation.
Shares tier infrastructure with 82 other crates: infrastructure-acquire, infrastructure-adapters-google-calendar, infrastructure-adapters-google-gmail, infrastructure-adapters-google-places, infrastructure-adapters-shodan, infrastructure-adapters-yelp, infrastructure-agent, infrastructure-ai, … (82 total).
_What this crate deliberately does NOT own is a judgment. No committed registry records one for it, so none is stated here._
Where it sits
| Tier (ontology) | infrastructure |
| Architectural role (taxonomy) | unclassified (baselined) |
| Location | crates/infrastructure/adapters-google-trends |
| Vocabulary in force (lexicon) | current |
Tier flow. Which tiers this crate's own edges cross.
flowchart LR n_infrastructure["infrastructure"] --> n_foundation["foundation"]
Dependencies
Runtime, in this workspace.
| Crate | Tier | Optional | Only on |
|---|---|---|---|
| `foundation-source-ingest` | foundation | no | always |
| `infrastructure-fetcher` | infrastructure | yes | always |
Runtime, from outside the workspace.
| Crate | Requirement | Features | Optional | Only on |
|---|---|---|---|---|
async-trait | ^0.1 | — | no | always |
chrono | ^0.4 | serde | no | always |
rand | ^0.8 | — | no | always |
reqwest | ^0.12 | json, cookies | no | always |
serde | ^1 | derive | no | always |
serde_json | ^1 | — | no | always |
thiserror | ^2 | — | no | always |
tokio | ^1 | sync, time | no | always |
tracing | ^0.1 | — | no | always |
Development, from outside the workspace.
| Crate | Requirement | Features | Optional | Only on |
|---|---|---|---|---|
tokio | ^1 | macros, rt-multi-thread, time | no | always |
wiremock | ^0.6 | — | no | always |
Build. None.
Depended on by. Nothing in this workspace.
Signal flow — what reaches this crate, and what it reaches.
flowchart LR SELF["infrastructure-adapters-google-trends"] SELF -->|runtime| n_foundation_source_ingest["foundation-source-ingest"] SELF -->|runtime| n_infrastructure_fetcher["infrastructure-fetcher"] classDef self fill:#1f883d,stroke:#1f883d,color:#fff; class SELF self;
Feature flags
| Feature | Enables | On by default |
|---|---|---|
default | secure-egress | yes |
secure-egress | dep:infrastructure-fetcher | yes |
flowchart LR n_default["default"] --> n_secure_egress["secure-egress"] n_secure_egress["secure-egress"] --> n_dep_infrastructure_fetcher["dep:infrastructure-fetcher"]
Targets
| Kind | Name | Source |
|---|---|---|
| lib | infrastructure_adapters_google_trends | `src/lib.rs` |
Error model
No public error type was detected: no public item declares a type named *Error, and no public signature returns one.
Operational characteristics
| Property | Evidence |
|---|---|
| async public surface | none detected |
| async runtime | yes |
| database access | none detected |
| network I/O | yes |
| unsafe code | none detected |
| environment variables | none detected |
No unsafe block, unsafe fn, unsafe impl or unsafe trait was found by the parser anywhere in this crate's source.
Configuration
No environment variable is read with a literal name anywhere in this crate. A variable whose key is computed at run time cannot be listed here, and is not claimed to be absent.
Related capabilities
No workspace crate depends on this one.
Verification
| Kind | Count |
|---|---|
| Unit tests | 17 |
| Integration tests | 0 |
| Examples | 0 |
| Doctests | 1 |
What the tests establish, by name:
collect_keyword_falls_back_to_zero_point_when_timeline_is_empty—src/client.rscollect_keyword_parses_explore_timeline_and_related_responses—src/client.rscollect_keyword_propagates_error_when_explore_request_fails—src/client.rscollect_keyword_tolerates_missing_related_widget—src/client.rscreating_a_client_succeeds—src/client.rsingest_collects_every_keyword_and_reports_no_errors_on_success—src/client.rsingest_counts_a_failed_keyword_without_aborting_the_batch—src/client.rsrate_limit_enforces_minimum_interval_between_requests—src/client.rsstrict_egress_client_is_constructible—src/client.rsstrip_xssi_prefix_is_noop_without_the_guard—src/client.rsstrip_xssi_prefix_removes_googles_json_hijacking_guard—src/client.rswith_base_url_overrides_the_configured_host—src/client.rsdefault_config_has_no_keywords_and_us_geo—src/config.rsdefault_config_is_invalid_without_keywords—src/config.rsnew_with_keywords_is_valid—src/config.rstrend_point_new_has_no_related_queries—src/types.rstrend_point_serializes_and_round_trips—src/types.rs
Documentation coverage
| Measure | Documented | Total |
|---|---|---|
| Public items with rustdoc | 0 | 0 |
Public modules with a //! block | 0 | 0 |
Metrics
| Metric | Value |
|---|---|
| Rust source files | 5 |
| Source lines | 1031 |
| Code lines | 675 |
| Public API items | 0 |
| Public modules | 0 |
| Tests | 17 |
| Examples | 0 |
| Cargo features | 2 |
| Direct runtime dependencies | 11 |
| Workspace reverse dependencies | 0 |
pie showData
title Rust source composition
"Code" : 675
"Blank or comment" : 356
Generation
Rendered by tools-corpus corpus readme from repository evidence alone, renderer schema 2, lexicon current. No model, network service or database was consulted. Regenerate with tools-corpus corpus readme --write; verify with --check.