Skip to main content

FolderSource

Trait FolderSource 

Source
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§

Source

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§

Source

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.

Source

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.

Source

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.

Source

fn can_create_folders(&self) -> bool

Whether the source can make folders. The default is false, which hides the picker’s “New folder” button.

Source

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".

Implementors§