1pub mod client;
60pub mod dexscreener;
61pub mod dexscreener_api;
62pub mod error;
63pub mod faster100x;
64pub mod lunarcrush;
65pub mod news;
66pub mod pocketuniverse;
67pub mod price;
68pub mod rugcheck;
69pub mod trenchbot;
70pub mod tweetscout;
71pub mod twitter;
72pub mod web_search;
73
74pub use dexscreener::{
77 analyze_token_market, get_token_info, get_top_pairs, get_trending_tokens, search_tokens,
78 ChainInfo, MarketAnalysis, TokenInfo, TokenPair,
79};
80
81pub use news::{
83 analyze_market_sentiment, get_crypto_news, get_trending_news, monitor_breaking_news,
84 LexiconSentimentAnalyzer, NewsAggregationResult, NewsArticle, NewsSource, SentimentAnalyzer,
85};
86
87pub use twitter::{
89 analyze_crypto_sentiment, get_user_tweets, search_tweets, SentimentAnalysis,
90 SentimentBreakdown, TwitterPost, TwitterSearchResult, TwitterUser,
91};
92
93pub use web_search::{
95 find_similar_pages, search_recent_news, search_web, summarize_web_content, ContentSummary,
96 SearchResult, WebSearchResult,
97};
98
99pub use lunarcrush::{
101 get_influencer_mentions, get_social_sentiment, get_trending_cryptos, InfluencerMention,
102 InfluencerMentionsResult, SentimentData, TrendingCrypto,
103};
104
105pub use faster100x::{
107 analyze_token_holders, get_holder_trends, get_whale_activity, ConcentrationRisk, HolderTrends,
108 TokenHolderAnalysis, WalletHolding, WhaleActivity,
109};
110
111pub use price::{get_token_price, get_token_prices_batch, TokenPriceResult};
113
114pub use rugcheck::{
116 analyze_token_risks, check_if_rugged, get_token_report, RiskAnalysis, RiskLevel,
117 RugCheckResult, TokenCheck, TokenHolder as RugCheckTokenHolder,
118};
119
120pub use trenchbot::{
122 analyze_creator_risk, analyze_token_bundles, check_bundle_risk, get_bundle_info,
123 BundleAnalysisResult, BundleResponse, BundleRiskCheck, CreatorAnalysisResult,
124};
125
126pub use pocketuniverse::{
128 analyze_rug_risk, check_rug_pull, check_rug_pull_raw, is_token_safe, DetailedRugAnalysis,
129 RugApiResponse, RugCheckResult as PocketUniverseRugCheck, SafetyCheck,
130};
131
132pub use tweetscout::{
134 analyze_account, analyze_social_network, get_account_info, get_account_score,
135 get_top_followers, get_top_friends, is_account_credible, AccountAnalysis, AccountInfo,
136 CredibilityCheck, SocialNetworkAnalysis,
137};
138
139pub use client::WebClient;
141pub use error::{Result, WebToolError};
142
143pub const VERSION: &str = env!("CARGO_PKG_VERSION");
145
146#[cfg(test)]
147mod tests {
148 use super::*;
149
150 #[test]
151 fn test_version_when_valid_should_start_with_semver_digit() {
152 assert!(
154 VERSION.starts_with("0.") || VERSION.starts_with("1."),
155 "VERSION should be a valid semver"
156 );
157 }
158
159 #[test]
160 fn test_version_when_called_should_not_be_empty() {
161 assert!(!VERSION.is_empty(), "VERSION should not be empty");
163 }
164
165 #[test]
166 fn test_version_when_called_should_contain_dots() {
167 assert!(
169 VERSION.contains('.'),
170 "VERSION should contain dots for semver format"
171 );
172 }
173
174 #[test]
175 fn test_version_when_called_should_be_valid_utf8() {
176 assert!(VERSION.is_ascii(), "VERSION should be valid ASCII");
178 }
179
180 #[test]
181 fn test_version_when_called_should_match_cargo_version() {
182 let version = env!("CARGO_PKG_VERSION");
184 assert_eq!(VERSION, version, "VERSION should match CARGO_PKG_VERSION");
185 }
186
187 #[test]
188 fn test_version_when_parsed_should_have_major_minor_patch() {
189 let parts: Vec<&str> = VERSION.split('.').collect();
191 assert!(
192 parts.len() >= 2,
193 "VERSION should have at least major.minor format"
194 );
195
196 assert!(
198 parts[0].parse::<u32>().is_ok(),
199 "Major version should be numeric"
200 );
201
202 let minor_part = parts[1].split('-').next().unwrap_or(parts[1]);
204 assert!(
205 minor_part.parse::<u32>().is_ok(),
206 "Minor version should be numeric"
207 );
208 }
209
210 #[test]
211 fn test_module_re_exports_are_accessible() {
212 use crate::{Result, WebClient, WebToolError, VERSION};
217
218 let _version: &str = VERSION;
220 let _error_type = std::marker::PhantomData::<WebToolError>;
221 let _result_type = std::marker::PhantomData::<Result<()>>;
222 let _client_type = std::marker::PhantomData::<WebClient>;
223 }
224
225 #[test]
226 fn test_dexscreener_re_exports_are_accessible() {
227 use crate::{ChainInfo, MarketAnalysis, TokenInfo, TokenPair};
229
230 let _chain_info_type = std::marker::PhantomData::<ChainInfo>;
231 let _market_analysis_type = std::marker::PhantomData::<MarketAnalysis>;
232 let _token_info_type = std::marker::PhantomData::<TokenInfo>;
233 let _token_pair_type = std::marker::PhantomData::<TokenPair>;
234 }
235
236 #[test]
237 fn test_news_re_exports_are_accessible() {
238 use crate::{NewsAggregationResult, NewsArticle, NewsSource};
240
241 let _news_aggregation_type = std::marker::PhantomData::<NewsAggregationResult>;
242 let _news_article_type = std::marker::PhantomData::<NewsArticle>;
243 let _news_source_type = std::marker::PhantomData::<NewsSource>;
244 }
245
246 #[test]
247 fn test_twitter_re_exports_are_accessible() {
248 use crate::{
250 SentimentAnalysis, SentimentBreakdown, TwitterPost, TwitterSearchResult, TwitterUser,
251 };
252
253 let _sentiment_analysis_type = std::marker::PhantomData::<SentimentAnalysis>;
254 let _sentiment_breakdown_type = std::marker::PhantomData::<SentimentBreakdown>;
255 let _twitter_post_type = std::marker::PhantomData::<TwitterPost>;
256 let _twitter_search_result_type = std::marker::PhantomData::<TwitterSearchResult>;
257 let _twitter_user_type = std::marker::PhantomData::<TwitterUser>;
258 }
259
260 #[test]
261 fn test_web_search_re_exports_are_accessible() {
262 use crate::{ContentSummary, SearchResult, WebSearchResult};
264
265 let _content_summary_type = std::marker::PhantomData::<ContentSummary>;
266 let _search_result_type = std::marker::PhantomData::<SearchResult>;
267 let _web_search_result_type = std::marker::PhantomData::<WebSearchResult>;
268 }
269
270 #[test]
271 fn test_lunarcrush_re_exports_are_accessible() {
272 use crate::{InfluencerMention, InfluencerMentionsResult, SentimentData, TrendingCrypto};
274
275 let _influencer_mention_type = std::marker::PhantomData::<InfluencerMention>;
276 let _influencer_mentions_result_type = std::marker::PhantomData::<InfluencerMentionsResult>;
277 let _sentiment_data_type = std::marker::PhantomData::<SentimentData>;
278 let _trending_crypto_type = std::marker::PhantomData::<TrendingCrypto>;
279 }
280
281 #[test]
282 fn test_faster100x_re_exports_are_accessible() {
283 use crate::{
285 ConcentrationRisk, HolderTrends, TokenHolderAnalysis, WalletHolding, WhaleActivity,
286 };
287
288 let _concentration_risk_type = std::marker::PhantomData::<ConcentrationRisk>;
289 let _holder_trends_type = std::marker::PhantomData::<HolderTrends>;
290 let _token_holder_analysis_type = std::marker::PhantomData::<TokenHolderAnalysis>;
291 let _wallet_holding_type = std::marker::PhantomData::<WalletHolding>;
292 let _whale_activity_type = std::marker::PhantomData::<WhaleActivity>;
293 }
294
295 #[test]
296 fn test_price_re_exports_are_accessible() {
297 use crate::TokenPriceResult;
299
300 let _token_price_result_type = std::marker::PhantomData::<TokenPriceResult>;
301 }
302
303 #[test]
304 fn test_rugcheck_re_exports_are_accessible() {
305 use crate::{RiskAnalysis, RiskLevel, RugCheckResult, RugCheckTokenHolder, TokenCheck};
307
308 let _risk_analysis_type = std::marker::PhantomData::<RiskAnalysis>;
309 let _risk_level_type = std::marker::PhantomData::<RiskLevel>;
310 let _rugcheck_result_type = std::marker::PhantomData::<RugCheckResult>;
311 let _token_check_type = std::marker::PhantomData::<TokenCheck>;
312 let _rugcheck_token_holder_type = std::marker::PhantomData::<RugCheckTokenHolder>;
313 }
314
315 #[test]
316 fn test_trenchbot_re_exports_are_accessible() {
317 use crate::{BundleAnalysisResult, BundleResponse, BundleRiskCheck, CreatorAnalysisResult};
319
320 let _bundle_analysis_result_type = std::marker::PhantomData::<BundleAnalysisResult>;
321 let _bundle_response_type = std::marker::PhantomData::<BundleResponse>;
322 let _bundle_risk_check_type = std::marker::PhantomData::<BundleRiskCheck>;
323 let _creator_analysis_result_type = std::marker::PhantomData::<CreatorAnalysisResult>;
324 }
325
326 #[test]
327 fn test_pocketuniverse_re_exports_are_accessible() {
328 use crate::{DetailedRugAnalysis, PocketUniverseRugCheck, RugApiResponse, SafetyCheck};
330
331 let _detailed_rug_analysis_type = std::marker::PhantomData::<DetailedRugAnalysis>;
332 let _pocket_universe_rug_check_type = std::marker::PhantomData::<PocketUniverseRugCheck>;
333 let _rug_api_response_type = std::marker::PhantomData::<RugApiResponse>;
334 let _safety_check_type = std::marker::PhantomData::<SafetyCheck>;
335 }
336
337 #[test]
338 fn test_tweetscout_re_exports_are_accessible() {
339 use crate::{AccountAnalysis, AccountInfo, CredibilityCheck, SocialNetworkAnalysis};
341
342 let _account_analysis_type = std::marker::PhantomData::<AccountAnalysis>;
343 let _account_info_type = std::marker::PhantomData::<AccountInfo>;
344 let _credibility_check_type = std::marker::PhantomData::<CredibilityCheck>;
345 let _social_network_analysis_type = std::marker::PhantomData::<SocialNetworkAnalysis>;
346 }
347
348 #[test]
349 fn test_all_function_re_exports_are_accessible() {
350 use crate::{
352 analyze_account, analyze_creator_risk, analyze_crypto_sentiment,
353 analyze_market_sentiment, analyze_rug_risk, analyze_social_network,
354 analyze_token_bundles, analyze_token_holders, analyze_token_market,
355 analyze_token_risks, check_bundle_risk, check_if_rugged, check_rug_pull,
356 check_rug_pull_raw, find_similar_pages, get_account_info, get_account_score,
357 get_bundle_info, get_crypto_news, get_holder_trends, get_influencer_mentions,
358 get_social_sentiment, get_token_info, get_token_price, get_token_prices_batch,
359 get_token_report, get_top_followers, get_top_friends, get_top_pairs,
360 get_trending_cryptos, get_trending_news, get_trending_tokens, get_user_tweets,
361 get_whale_activity, is_account_credible, is_token_safe, monitor_breaking_news,
362 search_recent_news, search_tokens, search_tweets, search_web, summarize_web_content,
363 };
364
365 let _analyze_token_market = analyze_token_market;
368 let _get_token_info = get_token_info;
369 let _get_top_pairs = get_top_pairs;
370 let _get_trending_tokens = get_trending_tokens;
371 let _search_tokens = search_tokens;
372
373 let _analyze_market_sentiment = analyze_market_sentiment;
374 let _get_crypto_news = get_crypto_news;
375 let _get_trending_news = get_trending_news;
376 let _monitor_breaking_news = monitor_breaking_news;
377
378 let _analyze_crypto_sentiment = analyze_crypto_sentiment;
379 let _get_user_tweets = get_user_tweets;
380 let _search_tweets = search_tweets;
381
382 let _find_similar_pages = find_similar_pages;
383 let _search_recent_news = search_recent_news;
384 let _search_web = search_web;
385 let _summarize_web_content = summarize_web_content;
386
387 let _get_influencer_mentions = get_influencer_mentions;
388 let _get_social_sentiment = get_social_sentiment;
389 let _get_trending_cryptos = get_trending_cryptos;
390
391 let _analyze_token_holders = analyze_token_holders;
392 let _get_holder_trends = get_holder_trends;
393 let _get_whale_activity = get_whale_activity;
394
395 let _get_token_price = get_token_price;
396 let _get_token_prices_batch = get_token_prices_batch;
397
398 let _analyze_token_risks = analyze_token_risks;
399 let _check_if_rugged = check_if_rugged;
400 let _get_token_report = get_token_report;
401
402 let _analyze_creator_risk = analyze_creator_risk;
403 let _analyze_token_bundles = analyze_token_bundles;
404 let _check_bundle_risk = check_bundle_risk;
405 let _get_bundle_info = get_bundle_info;
406
407 let _analyze_rug_risk = analyze_rug_risk;
408 let _check_rug_pull = check_rug_pull;
409 let _check_rug_pull_raw = check_rug_pull_raw;
410 let _is_token_safe = is_token_safe;
411
412 let _analyze_account = analyze_account;
413 let _analyze_social_network = analyze_social_network;
414 let _get_account_info = get_account_info;
415 let _get_account_score = get_account_score;
416 let _get_top_followers = get_top_followers;
417 let _get_top_friends = get_top_friends;
418 let _is_account_credible = is_account_credible;
419 }
420
421 #[test]
422 fn test_version_constant_is_static() {
423 let version_ref: &'static str = VERSION;
425 assert!(!version_ref.is_empty(), "VERSION should not be empty");
426 }
427
428 #[test]
429 fn test_module_declarations_are_public() {
430 let _client_mod = crate::client::WebClient::default;
435 let _dexscreener_mod = crate::dexscreener::get_token_info;
436 let _error_mod = std::marker::PhantomData::<crate::error::WebToolError>;
438 let _faster100x_mod = crate::faster100x::analyze_token_holders;
439 let _lunarcrush_mod = crate::lunarcrush::get_social_sentiment;
440 let _news_mod = crate::news::get_crypto_news;
441 let _pocketuniverse_mod = crate::pocketuniverse::check_rug_pull;
442 let _price_mod = crate::price::get_token_price;
443 let _rugcheck_mod = crate::rugcheck::get_token_report;
444 let _trenchbot_mod = crate::trenchbot::get_bundle_info;
445 let _tweetscout_mod = crate::tweetscout::get_account_info;
446 let _twitter_mod = crate::twitter::search_tweets;
447 let _web_search_mod = crate::web_search::search_web;
448 }
449}