using AIStudio.Tools.Rust; namespace AIStudio.Tools.Services; public sealed partial class RustService { public async Task SelectDirectory(string title, string? initialDirectory = null) { var encodedTitle = Uri.EscapeDataString(title); var result = initialDirectory is null ? await this.http.PostAsync($"/select/directory?title={encodedTitle}", null) : await this.http.PostAsJsonAsync($"/select/directory?title={encodedTitle}", new PreviousDirectory(initialDirectory), this.jsonRustSerializerOptions); if (!result.IsSuccessStatusCode) { this.logger!.LogError($"Failed to select a directory: '{result.StatusCode}'"); return new DirectorySelectionResponse(true, string.Empty); } return await result.Content.ReadFromJsonAsync(this.jsonRustSerializerOptions); } public async Task SelectFile(string title, FileTypeFilter[]? filter = null, string? initialFile = null) { var payload = new SelectFileOptions { Title = title, PreviousFile = initialFile is null ? null : new (initialFile), Filter = FileTypes.AsOneFileType(filter) }; var result = await this.http.PostAsJsonAsync("/select/file", payload, this.jsonRustSerializerOptions); if (!result.IsSuccessStatusCode) { this.logger!.LogError($"Failed to select a file: '{result.StatusCode}'"); return new FileSelectionResponse(true, string.Empty); } return await result.Content.ReadFromJsonAsync(this.jsonRustSerializerOptions); } public async Task SelectFiles(string title, FileTypeFilter[]? filter = null, string? initialFile = null) { var payload = new SelectFileOptions { Title = title, PreviousFile = initialFile is null ? null : new (initialFile), Filter = FileTypes.AsOneFileType(filter) }; var result = await this.http.PostAsJsonAsync("/select/files", payload, this.jsonRustSerializerOptions); if (!result.IsSuccessStatusCode) { this.logger!.LogError($"Failed to select files: '{result.StatusCode}'"); return new FilesSelectionResponse(true, Array.Empty()); } return await result.Content.ReadFromJsonAsync(this.jsonRustSerializerOptions); } /// /// Initiates a dialog to let the user select a file for a writing operation. /// /// The title of the save file dialog. /// Optional file type filters for filtering specific file formats. /// An optional initial file path to pre-fill in the dialog. /// A object containing information about whether the user canceled the /// operation and whether the select operation was successful. public async Task SaveFile(string title, FileTypeFilter[]? filter = null, string? initialFile = null) { var payload = new SaveFileOptions { Title = title, PreviousFile = initialFile is null ? null : new (initialFile), Filter = FileTypes.AsOneFileType(filter) }; var result = await this.http.PostAsJsonAsync("/save/file", payload, this.jsonRustSerializerOptions); if (!result.IsSuccessStatusCode) { this.logger!.LogError($"Failed to select a file for writing operation '{result.StatusCode}'"); return new FileSaveResponse(true, string.Empty); } return await result.Content.ReadFromJsonAsync(this.jsonRustSerializerOptions); } public async Task TryOpenPathInRuntimeFileManager(string path) { HttpResponseMessage result; try { result = await this.http.PostAsJsonAsync("/open/path", new OpenPathRequest(path), this.jsonRustSerializerOptions); } catch (HttpRequestException e) { this.logger!.LogWarning(e, "Failed to reach the Rust runtime file manager endpoint."); return new OpenPathResponse(false, TB("The runtime file manager endpoint is not available.")); } catch (TaskCanceledException e) { this.logger!.LogWarning(e, "Timed out while reaching the Rust runtime file manager endpoint."); return new OpenPathResponse(false, TB("The runtime file manager endpoint is not available.")); } try { if (!result.IsSuccessStatusCode) { this.logger!.LogWarning("Failed to open a path in the file manager through the Rust runtime: '{StatusCode}'", result.StatusCode); return new OpenPathResponse(false, string.Format(TB("The runtime file manager endpoint returned '{0}'."), result.StatusCode)); } var response = await result.Content.ReadFromJsonAsync(this.jsonRustSerializerOptions); var normalizedResponse = response.Success ? response : new OpenPathResponse(false, string.IsNullOrWhiteSpace(response.Issue) ? TB("The runtime file manager endpoint failed without details.") : response.Issue); return normalizedResponse; } catch (Exception e) { this.logger!.LogWarning(e, "Failed to process the Rust runtime file manager endpoint response."); return new OpenPathResponse(false, TB("The runtime file manager endpoint failed without details.")); } finally { result.Dispose(); } } }