Replace to_link with as_link

Co-authored-by: Cole Miller <cole@zed.dev>
This commit is contained in:
Agus Zubiaga 2025-08-13 10:54:24 -03:00
parent d8131278f1
commit 6ed2155b9a
6 changed files with 57 additions and 49 deletions

View file

@ -341,7 +341,7 @@ impl ContentBlock {
..
}) => {
if let Some(uri) = MentionUri::parse(&uri).log_err() {
uri.to_link()
uri.as_link().to_string()
} else {
uri.clone()
}

View file

@ -2,6 +2,7 @@ use agent::ThreadId;
use anyhow::{Context as _, Result, bail};
use prompt_store::{PromptId, UserPromptId};
use std::{
fmt,
ops::Range,
path::{Path, PathBuf},
};
@ -108,7 +109,6 @@ impl MentionUri {
.to_string_lossy()
.into_owned(),
MentionUri::Symbol { name, .. } => name.clone(),
// todo! better names
MentionUri::Thread { name, .. } => name.clone(),
MentionUri::TextThread { name, .. } => name.clone(),
MentionUri::Rule { name, .. } => name.clone(),
@ -118,63 +118,72 @@ impl MentionUri {
}
}
// todo! return something that implements display to avoid extra allocs
pub fn to_link(&self) -> String {
let name = self.name();
let uri = self.to_uri();
format!("[{name}]({uri})")
pub fn as_link<'a>(&'a self) -> MentionLink<'a> {
MentionLink(self)
}
pub fn to_uri(&self) -> String {
pub fn to_uri(&self) -> Url {
match self {
MentionUri::File(path) => {
format!("file://{}", path.display())
let mut url = Url::parse("file:///").unwrap();
url.set_path(&path.to_string_lossy());
url
}
MentionUri::Symbol {
path,
name,
line_range,
} => {
let query = url::form_urlencoded::Serializer::new(String::new())
.append_pair("symbol", name)
.finish();
format!(
"file://{}?{query}#L{}:{}",
path.display(),
let mut url = Url::parse("file:///").unwrap();
url.set_path(&path.to_string_lossy());
url.query_pairs_mut().append_pair("symbol", name);
url.set_fragment(Some(&format!(
"L{}:{}",
line_range.start + 1,
line_range.end + 1,
)
line_range.end + 1
)));
url
}
MentionUri::Selection { path, line_range } => {
format!(
"file://{}#L{}:{}",
path.display(),
let mut url = Url::parse("file:///").unwrap();
url.set_path(&path.to_string_lossy());
url.set_fragment(Some(&format!(
"L{}:{}",
line_range.start + 1,
line_range.end + 1,
)
line_range.end + 1
)));
url
}
MentionUri::Thread { name, id } => {
let query = url::form_urlencoded::Serializer::new(String::new())
.append_pair("name", name)
.finish();
format!("zed:///agent/thread/{id}?{query}")
let mut url = Url::parse("zed:///").unwrap();
url.set_path(&format!("/agent/thread/{id}"));
url.query_pairs_mut().append_pair("name", name);
url
}
MentionUri::TextThread { path, name } => {
let query = url::form_urlencoded::Serializer::new(String::new())
.append_pair("name", name)
.finish();
format!("zed:///agent/text-thread/{}?{query}", path.display())
let mut url = Url::parse("zed:///").unwrap();
url.set_path(&format!("/agent/text-thread/{}", path.to_string_lossy()));
url.query_pairs_mut().append_pair("name", name);
url
}
MentionUri::Rule { name, id } => {
let query = url::form_urlencoded::Serializer::new(String::new())
.append_pair("name", name)
.finish();
format!("zed:///agent/rule/{id}?{query}")
let mut url = Url::parse("zed:///").unwrap();
url.set_path(&format!("/agent/rule/{id}"));
url.query_pairs_mut().append_pair("name", name);
url
}
}
}
}
pub struct MentionLink<'a>(&'a MentionUri);
impl fmt::Display for MentionLink<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "[{}]({})", self.0.name(), self.0.to_uri())
}
}
fn single_query_param(url: &Url, name: &'static str) -> Result<Option<String>> {
let pairs = url.query_pairs().collect::<Vec<_>>();
match pairs.as_slice() {
@ -211,7 +220,7 @@ mod tests {
MentionUri::File(path) => assert_eq!(path.to_str().unwrap(), "/path/to/file.rs"),
_ => panic!("Expected File variant"),
}
assert_eq!(parsed.to_uri(), file_uri);
assert_eq!(parsed.to_uri().to_string(), file_uri);
}
#[test]
@ -231,7 +240,7 @@ mod tests {
}
_ => panic!("Expected Symbol variant"),
}
assert_eq!(parsed.to_uri(), symbol_uri);
assert_eq!(parsed.to_uri().to_string(), symbol_uri);
}
#[test]
@ -246,7 +255,7 @@ mod tests {
}
_ => panic!("Expected Selection variant"),
}
assert_eq!(parsed.to_uri(), selection_uri);
assert_eq!(parsed.to_uri().to_string(), selection_uri);
}
#[test]
@ -263,7 +272,7 @@ mod tests {
}
_ => panic!("Expected Thread variant"),
}
assert_eq!(parsed.to_uri(), thread_uri);
assert_eq!(parsed.to_uri().to_string(), thread_uri);
}
#[test]
@ -277,7 +286,7 @@ mod tests {
}
_ => panic!("Expected Rule variant"),
}
assert_eq!(parsed.to_uri(), rule_uri);
assert_eq!(parsed.to_uri().to_string(), rule_uri);
}
#[test]

View file

@ -113,7 +113,7 @@ impl AgentMessage {
}
}
MessageContent::Mention { uri, .. } => {
write!(markdown, "{}", uri.to_link()).ok();
write!(markdown, "{}", uri.as_link()).ok();
}
}
}
@ -1228,7 +1228,7 @@ impl AgentMessage {
}
}
language_model::MessageContent::Text(uri.to_link())
language_model::MessageContent::Text(uri.as_link().to_string())
}
};

View file

@ -555,7 +555,7 @@ impl ContextPickerCompletionProvider {
name: title.to_string(),
},
};
let new_text = format!("{} ", uri.to_link());
let new_text = format!("{} ", uri.as_link());
let new_text_len = new_text.len();
Completion {
@ -590,7 +590,7 @@ impl ContextPickerCompletionProvider {
id: rule.prompt_id.into(),
name: rule.title.to_string(),
};
let new_text = format!("{} ", uri.to_link());
let new_text = format!("{} ", uri.as_link());
let new_text_len = new_text.len();
Completion {
replace_range: source_range.clone(),
@ -656,7 +656,7 @@ impl ContextPickerCompletionProvider {
};
let file_uri = MentionUri::File(abs_path.into());
let new_text = format!("{} ", file_uri.to_link());
let new_text = format!("{} ", file_uri.as_link());
let new_text_len = new_text.len();
Some(Completion {
replace_range: source_range.clone(),
@ -698,7 +698,7 @@ impl ContextPickerCompletionProvider {
name: symbol.name.clone(),
line_range: symbol.range.start.0.row..symbol.range.end.0.row,
};
let new_text = format!("{} ", uri.to_link());
let new_text = format!("{} ", uri.as_link());
let new_text_len = new_text.len();
Some(Completion {
replace_range: source_range.clone(),

View file

@ -32,6 +32,7 @@ use project::{CompletionIntent, Project};
use prompt_store::PromptId;
use rope::Point;
use settings::{Settings as _, SettingsStore};
use std::fmt::Write as _;
use std::path::PathBuf;
use std::{
cell::RefCell, collections::BTreeMap, path::Path, process::ExitStatus, rc::Rc, sync::Arc,
@ -439,7 +440,7 @@ impl AcpThreadView {
acp::TextResourceContents {
mime_type: None,
text: mention.content.clone(),
uri: mention.uri.to_uri(),
uri: mention.uri.to_uri().to_string(),
},
),
}));
@ -614,8 +615,7 @@ impl AcpThreadView {
let path = PathBuf::from(&resource.uri);
let project_path = project.read(cx).project_path_for_absolute_path(&path, cx);
let start = text.len();
let content = MentionUri::File(path).to_uri();
text.push_str(&content);
let _ = write!(&mut text, "{}", MentionUri::File(path).to_uri());
let end = text.len();
if let Some(project_path) = project_path {
let filename: SharedString = project_path

View file

@ -90,7 +90,6 @@ impl From<Uuid> for UserPromptId {
}
}
// todo! remove me
impl std::fmt::Display for PromptId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {