Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions guards/github-guard/rust-guard/src/labels/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,15 +229,14 @@ fn repo_matches_scope(
}
}

fn first_matching_scope(owner: &str, repo: &str, ctx: &PolicyContext) -> Option<PolicyScopeEntry> {
fn first_matching_scope<'a>(owner: &str, repo: &str, ctx: &'a PolicyContext) -> Option<&'a PolicyScopeEntry> {
ctx.scopes
.iter()
.find(|scope| {
let scoped_owner = scope.scope_owner.as_deref().unwrap_or("");
let scoped_repo = scope.scope_repo.as_deref().unwrap_or("");
repo_matches_scope(scope.scope_kind, owner, repo, scoped_owner, scoped_repo)
})
.cloned()
}

fn format_integrity_label(prefix: &str, scope: &str, base: &str) -> String {
Expand Down
8 changes: 5 additions & 3 deletions guards/github-guard/rust-guard/src/labels/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
//! - `unapproved:<repo>` - Lower trust external contribution level
//! - (none) - Untrusted/external content

use std::borrow::Cow;

use serde_json::Value;

// Sub-modules
Expand Down Expand Up @@ -93,7 +95,7 @@ pub fn label_response_paths(
/// Extract the actual response from MCP wrapper format
/// MCP responses are wrapped in {"content":[{"type":"text","text":"..."}]}
/// where the text field contains stringified JSON
pub(crate) fn extract_mcp_response(response: &Value) -> Value {
pub(crate) fn extract_mcp_response(response: &Value) -> Cow<'_, Value> {
// Log the top-level keys to understand the structure
if let Some(obj) = response.as_object() {
let keys: Vec<&str> = obj.keys().map(|s| s.as_str()).collect();
Expand Down Expand Up @@ -128,7 +130,7 @@ pub(crate) fn extract_mcp_response(response: &Value) -> Value {
// Try to parse the text as JSON
if let Ok(parsed) = serde_json::from_str::<Value>(text) {
crate::log_debug("extract_mcp_response: parsed content[0].text as JSON");
return parsed;
return Cow::Owned(parsed);
} else {
crate::log_debug("extract_mcp_response: failed to parse text as JSON");
}
Expand All @@ -143,7 +145,7 @@ pub(crate) fn extract_mcp_response(response: &Value) -> Value {
// If we can't extract from MCP wrapper, return the original response
// (it might already be unwrapped or in a different format)
crate::log_debug("extract_mcp_response: using response as-is");
response.clone()
Cow::Borrowed(response)
}

// ============================================================================
Expand Down
4 changes: 2 additions & 2 deletions guards/github-guard/rust-guard/src/labels/response_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ pub fn label_response_items(
graphql_single_buf = [obj.clone()];
&graphql_single_buf
} else if actual_response.is_object() && !is_graphql_wrapper(&actual_response) && !is_search_result_wrapper(&actual_response) && !is_mcp_text_wrapper(&actual_response) {
single_item_buf = [actual_response.clone()];
single_item_buf = [actual_response.as_ref().clone()];
&single_item_buf
} else {
&[]
Expand Down Expand Up @@ -240,7 +240,7 @@ pub fn label_response_items(
} else if let Some(obj) = extract_graphql_single_object(&actual_response) {
vec![obj]
} else if actual_response.is_object() && !is_graphql_wrapper(&actual_response) && !is_search_result_wrapper(&actual_response) && !is_mcp_text_wrapper(&actual_response) {
vec![&actual_response]
vec![actual_response.as_ref()]
} else {
Vec::new()
};
Expand Down
Loading