Skip to content

Commit a50560f

Browse files
committed
chore: good rust
1 parent 0fc98e6 commit a50560f

21 files changed

Lines changed: 209 additions & 160 deletions

File tree

.github/workflows/ci.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,7 @@ jobs:
158158
checks: write
159159
packages: read
160160
env:
161-
# We cannot propagate the "missing_docs" flag, as otherwise other tests fail.
162-
RUSTFLAGS: "-Dwarnings -Dmissing_docs"
161+
RUSTDOCFLAGS: "-Dwarnings -Dmissing_docs"
163162
steps:
164163
- uses: actions/checkout@v4
165164

Cargo.lock

Lines changed: 0 additions & 41 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ tempfile = { version = "3", optional = true }
2525
[dev-dependencies]
2626
tokio-test = "0.4"
2727
tempfile = "3"
28-
serial_test = "3"
2928

3029
[profile.release]
3130
opt-level = "z" # Optimize for size
@@ -36,3 +35,36 @@ panic = "abort" # Smaller binary
3635

3736
[profile.production]
3837
inherits = "release"
38+
39+
[lints.rust]
40+
missing_docs = "deny"
41+
unsafe_code = "deny"
42+
rust_2018_idioms = "deny"
43+
trivial_casts = "deny"
44+
trivial_numeric_casts = "deny"
45+
unused_lifetimes = "deny"
46+
unused_qualifications = "deny"
47+
48+
[lints.clippy]
49+
correctness = "deny"
50+
complexity = "deny"
51+
perf = "deny"
52+
style = "deny"
53+
suspicious = "deny"
54+
unwrap_used = "deny"
55+
expect_used = "deny"
56+
panic = "deny"
57+
todo = "deny"
58+
unimplemented = "deny"
59+
dbg_macro = "deny"
60+
print_stdout = "deny"
61+
print_stderr = "deny"
62+
clone_on_ref_ptr = "deny"
63+
empty_structs_with_brackets = "deny"
64+
expl_impl_clone_on_copy = "deny"
65+
implicit_clone = "deny"
66+
manual_string_new = "deny"
67+
redundant_closure_for_method_calls = "deny"
68+
semicolon_if_nothing_returned = "deny"
69+
str_to_string = "deny"
70+
use_self = "deny"

src/error.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ pub enum PopMcpError {
2323
impl fmt::Display for PopMcpError {
2424
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2525
match self {
26-
PopMcpError::CommandExecution(msg) => write!(f, "Command execution error: {}", msg),
27-
PopMcpError::InvalidInput(msg) => write!(f, "Invalid input: {}", msg),
28-
PopMcpError::ResourceNotFound(msg) => write!(f, "Resource not found: {}", msg),
29-
PopMcpError::NetworkError(msg) => write!(f, "Network error: {}", msg),
30-
PopMcpError::Internal(msg) => write!(f, "Internal error: {}", msg),
26+
Self::CommandExecution(msg) => write!(f, "Command execution error: {}", msg),
27+
Self::InvalidInput(msg) => write!(f, "Invalid input: {}", msg),
28+
Self::ResourceNotFound(msg) => write!(f, "Resource not found: {}", msg),
29+
Self::NetworkError(msg) => write!(f, "Network error: {}", msg),
30+
Self::Internal(msg) => write!(f, "Internal error: {}", msg),
3131
}
3232
}
3333
}
@@ -36,12 +36,12 @@ impl std::error::Error for PopMcpError {}
3636

3737
impl From<anyhow::Error> for PopMcpError {
3838
fn from(err: anyhow::Error) -> Self {
39-
PopMcpError::Internal(err.to_string())
39+
Self::Internal(err.to_string())
4040
}
4141
}
4242

4343
impl From<reqwest::Error> for PopMcpError {
4444
fn from(err: reqwest::Error) -> Self {
45-
PopMcpError::NetworkError(err.to_string())
45+
Self::NetworkError(err.to_string())
4646
}
4747
}

src/executor.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@ use std::process::Command;
66

77
use crate::error::{PopMcpError, PopMcpResult};
88

9-
/// Output from command execution
9+
/// Output from command execution.
1010
#[derive(Debug, Clone)]
1111
pub struct CommandOutput {
12+
/// Standard output from the command.
1213
pub stdout: String,
14+
/// Standard error from the command.
1315
pub stderr: String,
16+
/// Whether the command exited successfully.
1417
pub success: bool,
1518
}
1619

@@ -31,7 +34,7 @@ impl CommandOutput {
3134
}
3235

3336
if result.is_empty() {
34-
"(Command succeeded but produced no output)".to_string()
37+
"(Command succeeded but produced no output)".to_owned()
3538
} else {
3639
result
3740
}
@@ -49,6 +52,7 @@ pub struct PopExecutor {
4952
}
5053

5154
impl PopExecutor {
55+
/// Create a new executor with default settings.
5256
pub fn new() -> Self {
5357
Self::default()
5458
}
@@ -112,8 +116,8 @@ mod tests {
112116
#[test]
113117
fn command_output_combines_streams() {
114118
let output = CommandOutput {
115-
stdout: "stdout content".to_string(),
116-
stderr: "stderr content".to_string(),
119+
stdout: "stdout content".to_owned(),
120+
stderr: "stderr content".to_owned(),
117121
success: true,
118122
};
119123
assert!(output.combined().contains("stderr content"));

src/resources.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,20 @@ use rmcp::ErrorData as McpError;
66
use schemars::JsonSchema;
77
use serde::{Deserialize, Serialize};
88

9+
/// Parameters for the search_documentation tool.
910
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema)]
1011
pub struct SearchDocumentationParams {
12+
/// Search query or topic.
1113
#[schemars(description = "Search query or topic")]
1214
pub query: String,
15+
/// Scope to limit search to specific documentation.
1316
#[schemars(
1417
description = "Limit search to specific documentation: 'ink', 'pop', 'xcm', 'dedot', or 'all'"
1518
)]
1619
pub scope: Option<String>,
1720
}
1821

22+
/// Search through Polkadot documentation for specific topics.
1923
pub async fn search_documentation(
2024
params: SearchDocumentationParams,
2125
) -> Result<CallToolResult, McpError> {
@@ -126,6 +130,7 @@ async fn fetch_external_doc(url: &str) -> Result<String> {
126130
Ok(text)
127131
}
128132

133+
/// Search documentation with the given query and optional scope filter.
129134
pub async fn search_docs(query: &str, scope: Option<String>) -> Result<CallToolResult> {
130135
let search_scope = match scope.as_deref() {
131136
Some("ink") => "ink",
@@ -151,7 +156,7 @@ pub async fn search_docs(query: &str, scope: Option<String>) -> Result<CallToolR
151156
}
152157

153158
let content = match &res.source {
154-
ResourceSource::Embedded(text) => text.to_string(),
159+
ResourceSource::Embedded(text) => (*text).to_owned(),
155160
ResourceSource::External(url) => match fetch_external_doc(url).await {
156161
Ok(text) => text,
157162
Err(e) => {
@@ -209,16 +214,17 @@ pub async fn search_docs(query: &str, scope: Option<String>) -> Result<CallToolR
209214
Ok(CallToolResult::success(vec![Content::text(response)]))
210215
}
211216

217+
/// List all available documentation resources.
212218
pub async fn list_resources() -> Result<ListResourcesResult> {
213219
let resources: Vec<Resource> = RESOURCES
214220
.iter()
215221
.map(|res| {
216222
Resource::new(
217223
rmcp::model::RawResource {
218-
uri: res.uri.to_string(),
219-
name: res.name.to_string(),
224+
uri: (*res.uri).to_owned(),
225+
name: (*res.name).to_owned(),
220226
description: Some(format!("{} resource", res.scope)),
221-
mime_type: Some("text/plain".to_string()),
227+
mime_type: Some("text/plain".to_owned()),
222228
title: None,
223229
size: None,
224230
icons: None,
@@ -234,18 +240,19 @@ pub async fn list_resources() -> Result<ListResourcesResult> {
234240
})
235241
}
236242

243+
/// Read a documentation resource by URI.
237244
pub async fn read_resource(uri: &str) -> Result<ReadResourceResult> {
238245
for res in RESOURCES {
239246
if res.uri == uri {
240247
let content = match &res.source {
241-
ResourceSource::Embedded(text) => text.to_string(),
248+
ResourceSource::Embedded(text) => (*text).to_owned(),
242249
ResourceSource::External(url) => fetch_external_doc(url).await?,
243250
};
244251

245252
return Ok(ReadResourceResult {
246253
contents: vec![rmcp::model::ResourceContents::text(
247254
content,
248-
uri.to_string(),
255+
(*uri).to_owned(),
249256
)],
250257
});
251258
}

0 commit comments

Comments
 (0)