pub trait FolderSource: 'static {
// Required method
fn list(
&self,
dir: &SourcePath,
page: Option<PageToken>,
cx: &mut App,
) -> Task<Result<FolderPage, ListError>> ⓘ;
// Provided methods
fn home(&self) -> Option<SourcePath> { ... }
fn path_style(&self) -> PathStyle { ... }
fn env(&self, name: &str) -> Option<String> { ... }
fn can_create_folders(&self) -> bool { ... }
fn create_folder(
&self,
parent: &SourcePath,
name: &str,
cx: &mut App,
) -> Task<Result<SourcePath, CreateFolderError>> ⓘ { ... }
}Expand description
Where a FolderPicker lists folders from: the
local disk, an SSH session, a bucket, an API. The picker never waits
for a source. It calls list and awaits the task, and it drops the
task to cancel it.
A source lists one directory a page at a time. It should give entries in the order to show: the picker keeps that order and sorts nothing, so a source that pages must sort across its pages itself. Folders that repeat across pages, by name, show once.
use gpui_cn::{FolderEntry, FolderPage, FolderSource, ListError, PageToken, SourcePath};
use gpui_kit::{App, AppContext as _, Task};
/// A source over a list of names, ten to a page.
struct Names(Vec<String>);
impl FolderSource for Names {
fn list(
&self,
_dir: &SourcePath,
page: Option<PageToken>,
cx: &mut App,
) -> Task<Result<FolderPage, ListError>> {
let start = page.and_then(|t| t.as_str().parse().ok()).unwrap_or(0);
let end = (start + 10).min(self.0.len());
let names = self.0[start..end].to_vec();
let more = (end < self.0.len()).then(|| PageToken::new(end.to_string()));
// Any work goes on a task: a request, a query, a disk read.
cx.background_spawn(async move {
let page = FolderPage::new(names.into_iter().map(FolderEntry::new));
Ok(match more {
Some(token) => page.with_next(token),
None => page,
})
})
}
}Required Methods§
Sourcefn list(
&self,
dir: &SourcePath,
page: Option<PageToken>,
cx: &mut App,
) -> Task<Result<FolderPage, ListError>> ⓘ
fn list( &self, dir: &SourcePath, page: Option<PageToken>, cx: &mut App, ) -> Task<Result<FolderPage, ListError>> ⓘ
Lists the folders of dir, from the start when page is None,
or else from the page token a previous page named. A folder whose
name is empty, . or .., or has a separator of the source’s style
or a control character is dropped by the picker.
Provided Methods§
Sourcefn home(&self) -> Option<SourcePath>
fn home(&self) -> Option<SourcePath>
The source’s home folder, which a leading ~ in the typed path
stands for and where a picker with no start of its own begins. The
default is None: a source with no home does not expand ~, so a
typed ~ is an ordinary name, and the picker starts at the root.
A remote or virtual source gives its own, made with
path_style.
Sourcefn path_style(&self) -> PathStyle
fn path_style(&self) -> PathStyle
How the source writes its paths. The default is the style of the
machine the application runs on. A source for another machine
names its own: a Linux server is PathStyle::posix whatever
the client is.
Sourcefn env(&self, name: &str) -> Option<String>
fn env(&self, name: &str) -> Option<String>
The value of the variable name, for %NAME% in a Windows-style
path that is pasted. The default knows none: a remote source never
reads the host’s environment.
Sourcefn can_create_folders(&self) -> bool
fn can_create_folders(&self) -> bool
Whether the source can make folders. The default is false, which
hides the picker’s “New folder” button.
Sourcefn create_folder(
&self,
parent: &SourcePath,
name: &str,
cx: &mut App,
) -> Task<Result<SourcePath, CreateFolderError>> ⓘ
fn create_folder( &self, parent: &SourcePath, name: &str, cx: &mut App, ) -> Task<Result<SourcePath, CreateFolderError>> ⓘ
Makes the folder name inside parent and answers with its path.
The picker has checked name already: it is not empty, has no
separator, and is not . or ... Answer
CreateFolderError::Exists when something has that name. The
picker lists the directory again afterward, so the new folder
shows in the order the source lists. The default answers
CreateFolderError::Unsupported.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".