Browse Source

docs(rust) add rustdocs to the crates (#723)

Lucas Fernandes Nogueira 5 years ago
parent
commit
6d23b0673e
46 changed files with 929 additions and 212 deletions
  1. 3 1
      cli/tauri-bundler/src/bundle.rs
  2. 3 3
      cli/tauri-bundler/src/bundle/appimage_bundle.rs
  3. 2 0
      cli/tauri-bundler/src/bundle/category.rs
  4. 7 0
      cli/tauri-bundler/src/bundle/common.rs
  5. 9 4
      cli/tauri-bundler/src/bundle/deb_bundle.rs
  6. 3 2
      cli/tauri-bundler/src/bundle/dmg_bundle.rs
  7. 3 0
      cli/tauri-bundler/src/bundle/ios_bundle.rs
  8. 2 2
      cli/tauri-bundler/src/bundle/msi_bundle.rs
  9. 12 5
      cli/tauri-bundler/src/bundle/osx_bundle.rs
  10. 13 0
      cli/tauri-bundler/src/bundle/path_utils.rs
  11. 2 0
      cli/tauri-bundler/src/bundle/rpm_bundle.rs
  12. 170 38
      cli/tauri-bundler/src/bundle/settings.rs
  13. 31 11
      cli/tauri-bundler/src/bundle/wix.rs
  14. 2 1
      cli/tauri-bundler/src/main.rs
  15. 189 0
      cli/tauri.js/src/types/config.ts
  16. 27 4
      tauri-api/src/cli.rs
  17. 11 44
      tauri-api/src/command.rs
  18. 113 49
      tauri-api/src/config.rs
  19. 10 0
      tauri-api/src/dir.rs
  20. 2 0
      tauri-api/src/file.rs
  21. 7 0
      tauri-api/src/file/extract.rs
  22. 13 2
      tauri-api/src/http.rs
  23. 22 0
      tauri-api/src/lib.rs
  24. 23 3
      tauri-api/src/notification.rs
  25. 51 16
      tauri-api/src/path.rs
  26. 38 0
      tauri-api/src/rpc.rs
  27. 2 0
      tauri-api/src/tcp.rs
  28. 13 0
      tauri-utils/src/lib.rs
  29. 8 0
      tauri-utils/src/platform.rs
  30. 1 1
      tauri-utils/src/process.rs
  31. 1 1
      tauri/Cargo.toml
  32. 19 0
      tauri/src/app.rs
  33. 2 1
      tauri/src/app/runner.rs
  34. 1 0
      tauri/src/cli.rs
  35. 3 0
      tauri/src/endpoints.rs
  36. 50 19
      tauri/src/endpoints/cmd.rs
  37. 3 0
      tauri/src/endpoints/dialog.rs
  38. 10 0
      tauri/src/endpoints/file_system.rs
  39. 1 1
      tauri/src/endpoints/http.rs
  40. 3 3
      tauri/src/endpoints/notification.rs
  41. 1 0
      tauri/src/endpoints/salt.rs
  42. 9 0
      tauri/src/event.rs
  43. 23 1
      tauri/src/lib.rs
  44. 5 0
      tauri/src/salt.rs
  45. 1 0
      tauri/src/server.rs
  46. 5 0
      tauri/src/settings.rs

+ 3 - 1
cli/tauri-bundler/src/bundle.rs

@@ -20,6 +20,8 @@ pub use self::settings::{BuildArtifact, PackageType, Settings};
 
 use std::path::PathBuf;
 
+/// Bundles the project.
+/// Returns the list of paths where the bundles can be found.
 pub fn bundle_project(settings: Settings) -> crate::Result<Vec<PathBuf>> {
   let mut paths = Vec::new();
   let package_types = settings.package_types()?;
@@ -49,7 +51,7 @@ pub fn bundle_project(settings: Settings) -> crate::Result<Vec<PathBuf>> {
   Ok(paths)
 }
 
-// Check to see if there are icons in the settings struct
+/// Check to see if there are icons in the settings struct
 pub fn check_icons(settings: &Settings) -> crate::Result<bool> {
   // make a peekable iterator of the icon_files
   let mut iter = settings.icon_files().peekable();

+ 3 - 3
cli/tauri-bundler/src/bundle/appimage_bundle.rs

@@ -23,9 +23,9 @@ lazy_static! {
   };
 }
 
-// bundle the project.
+/// Bundles the project.
+/// Returns a vector of PathBuf that shows where the AppImage was created.
 pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
-
   // prerequisite: check if mksquashfs (part of squashfs-tools) is installed
   Command::new("mksquashfs")
     .arg("-version")
@@ -50,7 +50,7 @@ pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
   let package_dir = base_dir.join(&package_base_name);
 
   // generate deb_folder structure
-  deb_bundle::generate_folders(settings, &package_dir)?;
+  deb_bundle::generate_data(settings, &package_dir)?;
 
   let output_path = settings.project_out_directory().join("bundle/appimage");
   if output_path.exists() {

+ 2 - 0
cli/tauri-bundler/src/bundle/category.rs

@@ -10,6 +10,8 @@ const OSX_APP_CATEGORY_PREFIX: &str = "public.app-category.";
 // TODO: RIght now, these categories correspond to LSApplicationCategoryType
 // values for OS X.  There are also some additional GNOME registered categories
 // that don't fit these; we should add those here too.
+/// The possible app categories.
+/// Corresponds to `LSApplicationCategoryType` on macOS and the GNOME desktop categories on Debian.
 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
 pub enum AppCategory {
   Business,

+ 7 - 0
cli/tauri-bundler/src/bundle/common.rs

@@ -30,21 +30,25 @@ pub fn create_file(path: &Path) -> crate::Result<BufWriter<File>> {
   Ok(BufWriter::new(file))
 }
 
+/// Makes a symbolic link to a directory.
 #[cfg(unix)]
 fn symlink_dir(src: &Path, dst: &Path) -> io::Result<()> {
   std::os::unix::fs::symlink(src, dst)
 }
 
+/// Makes a symbolic link to a directory.
 #[cfg(windows)]
 fn symlink_dir(src: &Path, dst: &Path) -> io::Result<()> {
   std::os::windows::fs::symlink_dir(src, dst)
 }
 
+/// Makes a symbolic link to a file.
 #[cfg(unix)]
 fn symlink_file(src: &Path, dst: &Path) -> io::Result<()> {
   std::os::unix::fs::symlink(src, dst)
 }
 
+/// Makes a symbolic link to a file.
 #[cfg(windows)]
 fn symlink_file(src: &Path, dst: &Path) -> io::Result<()> {
   std::os::windows::fs::symlink_file(src, dst)
@@ -157,6 +161,8 @@ pub fn print_finished(output_paths: &Vec<PathBuf>) -> crate::Result<()> {
   Ok(())
 }
 
+/// Safely adds the terminal attribute to the terminal output.
+/// If the terminal doesn't support the attribute, does nothing.
 fn safe_term_attr<T: term::Terminal + ?Sized>(
   output: &mut Box<T>,
   attr: term::Attr,
@@ -167,6 +173,7 @@ fn safe_term_attr<T: term::Terminal + ?Sized>(
   }
 }
 
+/// Prints a formatted bundle progress to stderr.
 fn print_progress(step: &str, msg: &str) -> crate::Result<()> {
   if let Some(mut output) = term::stderr() {
     safe_term_attr(&mut output, term::Attr::Bold)?;

+ 9 - 4
cli/tauri-bundler/src/bundle/deb_bundle.rs

@@ -38,6 +38,8 @@ use std::fs::{self, File};
 use std::io::{self, Write};
 use std::path::{Path, PathBuf};
 
+/// Bundles the project.
+/// Returns a vector of PathBuf that shows where the DEB was created.
 pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
   let arch = match settings.binary_arch() {
     "x86" => "i386",
@@ -60,8 +62,8 @@ pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
   }
   let package_path = base_dir.join(package_name);
 
-  let data_dir =
-    generate_folders(settings, &package_dir).with_context(|| "Failed to build folders")?;
+  let data_dir = generate_data(settings, &package_dir)
+    .with_context(|| "Failed to build data folders and files")?;
   // Generate control files.
   let control_dir = package_dir.join("control");
   generate_control_file(settings, arch, &control_dir, &data_dir)
@@ -87,7 +89,8 @@ pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
   Ok(vec![package_path])
 }
 
-pub fn generate_folders(settings: &Settings, package_dir: &Path) -> crate::Result<PathBuf> {
+/// Generate the debian data folders and files.
+pub fn generate_data(settings: &Settings, package_dir: &Path) -> crate::Result<PathBuf> {
   // Generate data files.
   let data_dir = package_dir.join("data");
   let bin_name = settings.binary_name();
@@ -114,6 +117,7 @@ pub fn generate_folders(settings: &Settings, package_dir: &Path) -> crate::Resul
   Ok(data_dir)
 }
 
+/// Generates the bootstrap script file.
 fn generate_bootstrap_file(settings: &Settings, data_dir: &Path) -> crate::Result<()> {
   let bin_name = settings.binary_name();
   let bin_dir = data_dir.join("usr/bin");
@@ -124,7 +128,7 @@ fn generate_bootstrap_file(settings: &Settings, data_dir: &Path) -> crate::Resul
   write!(
     bootstrapper_file,
     "#!/usr/bin/env sh
-# This bootstraps the $PATH for Tauri, so environments are available.
+# This bootstraps the environment for Tauri, so environments are available.
 export NVM_DIR=\"$([ -z \"${{XDG_CONFIG_HOME-}}\" ] && printf %s \"${{HOME}}/.nvm\" || printf %s \"${{XDG_CONFIG_HOME}}/nvm\")\"
 [ -s \"$NVM_DIR/nvm.sh\" ] && . \"$NVM_DIR/nvm.sh\"
 
@@ -210,6 +214,7 @@ fn generate_desktop_file(settings: &Settings, data_dir: &Path) -> crate::Result<
   Ok(())
 }
 
+/// Generates the debian control file and stores it under the `control_dir`.
 fn generate_control_file(
   settings: &Settings,
   arch: &str,

+ 3 - 2
cli/tauri-bundler/src/bundle/dmg_bundle.rs

@@ -9,9 +9,10 @@ use std::fs::{self, write};
 use std::path::PathBuf;
 use std::process::{Command, Stdio};
 
-// create script files to bundle project and execute bundle_script.
+/// Bundles the project.
+/// Returns a vector of PathBuf that shows where the DMG was created.
 pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
-  // generate the app.app folder
+  // generate the .app bundle
   osx_bundle::bundle_project(settings)?;
 
   let app_name = settings.bundle_name();

+ 3 - 0
cli/tauri-bundler/src/bundle/ios_bundle.rs

@@ -22,6 +22,8 @@ use std::fs::{self, File};
 use std::io::Write;
 use std::path::{Path, PathBuf};
 
+/// Bundles the project.
+/// Returns a vector of PathBuf that shows where the .app was created.
 pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
   common::print_warning("iOS bundle support is still experimental.")?;
 
@@ -123,6 +125,7 @@ fn generate_icon_files(bundle_dir: &Path, settings: &Settings) -> crate::Result<
   Ok(filenames)
 }
 
+/// Generates the Info.plist file
 fn generate_info_plist(
   bundle_dir: &Path,
   settings: &Settings,

+ 2 - 2
cli/tauri-bundler/src/bundle/msi_bundle.rs

@@ -5,8 +5,8 @@ use super::wix;
 use std;
 use std::path::PathBuf;
 
-// Runs all of the commands to build the MSI installer.
-// Returns a vector of PathBuf that shows where the MSI was created.
+/// Runs all of the commands to build the MSI installer.
+/// Returns a vector of PathBuf that shows where the MSI was created.
 pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
   let wix_path = PathBuf::from("./WixTools");
 

+ 12 - 5
cli/tauri-bundler/src/bundle/osx_bundle.rs

@@ -34,6 +34,8 @@ use std::io::{self, BufWriter};
 use std::path::{Path, PathBuf};
 use std::process::{Command, Stdio};
 
+/// Bundles the project.
+/// Returns a vector of PathBuf that shows where the .app was created.
 pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
   let app_bundle_name = format!("{}.app", settings.bundle_name());
   common::print_bundling(&app_bundle_name)?;
@@ -82,6 +84,7 @@ pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
   Ok(vec![app_bundle_path])
 }
 
+// Copies the app's binary to the bundle.
 fn copy_binary_to_bundle(bundle_directory: &Path, settings: &Settings) -> crate::Result<()> {
   let dest_dir = bundle_directory.join("MacOS");
   common::copy_file(
@@ -90,13 +93,14 @@ fn copy_binary_to_bundle(bundle_directory: &Path, settings: &Settings) -> crate:
   )
 }
 
+// Creates the bootstrap script file.
 fn create_bootstrapper(bundle_dir: &Path, settings: &Settings) -> crate::Result<()> {
   let file = &mut common::create_file(&bundle_dir.join("MacOS/__bootstrapper"))?;
   // Create a shell script to bootstrap the  $PATH for Tauri, so environments like node are available.
   write!(
     file,
     "#!/usr/bin/env sh
-# This bootstraps the $PATH for Tauri, so environments are available.
+# This bootstraps the environment for Tauri, so environments are available.
 
 if [ -e ~/.bash_profile ]
 then 
@@ -142,6 +146,7 @@ exit 0",
   Ok(())
 }
 
+// Creates the Info.plist file.
 fn create_info_plist(
   bundle_dir: &Path,
   bundle_icon_file: Option<PathBuf>,
@@ -266,6 +271,7 @@ fn create_info_plist(
   Ok(())
 }
 
+// Copies the framework under `{src_dir}/{framework}.framework` to `{dest_dir}/{framework}.framework`.
 fn copy_framework_from(dest_dir: &Path, framework: &str, src_dir: &Path) -> crate::Result<bool> {
   let src_name = format!("{}.framework", framework);
   let src_path = src_dir.join(&src_name);
@@ -277,6 +283,7 @@ fn copy_framework_from(dest_dir: &Path, framework: &str, src_dir: &Path) -> crat
   }
 }
 
+// Copies the OSX bundle frameworks to the .app
 fn copy_frameworks_to_bundle(bundle_directory: &Path, settings: &Settings) -> crate::Result<()> {
   let frameworks = settings.osx_frameworks();
   if frameworks.is_empty() {
@@ -321,9 +328,9 @@ fn copy_frameworks_to_bundle(bundle_directory: &Path, settings: &Settings) -> cr
   Ok(())
 }
 
-/// Given a list of icon files, try to produce an ICNS file in the resources
-/// directory and return the path to it.  Returns `Ok(None)` if no usable icons
-/// were provided.
+// Given a list of icon files, try to produce an ICNS file in the resources
+// directory and return the path to it.  Returns `Ok(None)` if no usable icons
+// were provided.
 fn create_icns_file(
   resources_dir: &PathBuf,
   settings: &Settings,
@@ -408,7 +415,7 @@ fn create_icns_file(
   }
 }
 
-/// Converts an image::DynamicImage into an icns::Image.
+// Converts an image::DynamicImage into an icns::Image.
 fn make_icns_image(img: image::DynamicImage) -> io::Result<icns::Image> {
   let pixel_format = match img.color() {
     image::ColorType::Rgba8 => icns::PixelFormat::RGBA,

+ 13 - 0
cli/tauri-bundler/src/bundle/path_utils.rs

@@ -1,17 +1,20 @@
 use std::fs::{create_dir, create_dir_all, read_dir, remove_dir_all};
 use std::path::{Path, PathBuf};
 
+/// Directory options.
 #[derive(Clone)]
 pub struct DirOpts {
   pub depth: u64,
 }
 
+/// File options.
 pub struct FileOpts {
   pub overwrite: bool,
   pub skip: bool,
   pub buffer_size: usize,
 }
 
+/// Copy options.
 #[derive(Clone)]
 pub struct Options {
   pub overwrite: bool,
@@ -22,6 +25,7 @@ pub struct Options {
   pub depth: u64,
 }
 
+/// Directory information descriptor
 pub struct DirInfo {
   pub size: u64,
   pub files: Vec<String>,
@@ -57,6 +61,8 @@ impl Default for FileOpts {
   }
 }
 
+/// Creates the given directory path,
+/// erasing it first if specified.
 pub fn create<P>(path: P, erase: bool) -> crate::Result<()>
 where
   P: AsRef<Path>,
@@ -67,6 +73,8 @@ where
   Ok(create_dir(&path)?)
 }
 
+/// Creates all of the directories of the specified path,
+/// erasing it first if specified.
 pub fn create_all<P>(path: P, erase: bool) -> crate::Result<()>
 where
   P: AsRef<Path>,
@@ -77,6 +85,7 @@ where
   Ok(create_dir_all(&path)?)
 }
 
+/// Removes the directory if it exists.
 pub fn remove<P: AsRef<Path>>(path: P) -> crate::Result<()> {
   if path.as_ref().exists() {
     Ok(remove_dir_all(path)?)
@@ -85,6 +94,7 @@ pub fn remove<P: AsRef<Path>>(path: P) -> crate::Result<()> {
   }
 }
 
+/// Copy file with the given options.
 pub fn copy_file<P, Q>(from: P, to: Q, options: &FileOpts) -> crate::Result<u64>
 where
   P: AsRef<Path>,
@@ -124,6 +134,7 @@ where
   Ok(std::fs::copy(from, to)?)
 }
 
+/// Copies the directory with the given options.
 #[allow(dead_code)]
 pub fn copy<P, Q>(from: P, to: Q, options: &Options) -> crate::Result<u64>
 where
@@ -210,6 +221,7 @@ where
   Ok(result)
 }
 
+/// Gets the DirInfo from the directory path with the given options.
 pub fn get_dir_info<P>(path: P, options: &DirOpts) -> crate::Result<DirInfo>
 where
   P: AsRef<Path>,
@@ -223,6 +235,7 @@ where
   _get_dir_info(path, depth)
 }
 
+/// Gets the DirInfo from the directory with the given depth.
 fn _get_dir_info<P>(path: P, mut depth: u64) -> crate::Result<DirInfo>
 where
   P: AsRef<Path>,

+ 2 - 0
cli/tauri-bundler/src/bundle/rpm_bundle.rs

@@ -2,6 +2,8 @@ use crate::Settings;
 
 use std::path::PathBuf;
 
+/// Bundles the project.
+/// Not implemented yet.
 pub fn bundle_project(_settings: &Settings) -> crate::Result<Vec<PathBuf>> {
   unimplemented!();
 }

+ 170 - 38
cli/tauri-bundler/src/bundle/settings.rs

@@ -15,21 +15,31 @@ use std::fs::File;
 use std::io::Read;
 use std::path::{Path, PathBuf};
 
+/// The type of the package we're bundling.
 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
 pub enum PackageType {
+  /// The macOS bundle (.app).
   OsxBundle,
+  /// The iOS app bundle.
   IosBundle,
+  /// The Windows bundle (.msi).
   #[cfg(target_os = "windows")]
   WindowsMsi,
+  /// The Linux Debian package bundle (.deb).
   Deb,
+  /// The Linux RPM bundle (.rpm).
   Rpm,
+  /// The Linux AppImage bundle (.AppImage).
   AppImage,
+  /// The macOS DMG bundle (.dmg).
   Dmg,
 }
 
 impl PackageType {
+  /// Maps a short name to a PackageType.
+  /// Possible values are "deb", "ios", "msi", "osx", "rpm", "appimage", "dmg".
   pub fn from_short_name(name: &str) -> Option<PackageType> {
-    // Other types we may eventually want to support: apk
+    // Other types we may eventually want to support: apk.
     match name {
       "deb" => Some(PackageType::Deb),
       "ios" => Some(PackageType::IosBundle),
@@ -43,6 +53,7 @@ impl PackageType {
     }
   }
 
+  /// Gets the short name of this PackageType.
   pub fn short_name(&self) -> &'static str {
     match *self {
       PackageType::Deb => "deb",
@@ -56,6 +67,7 @@ impl PackageType {
     }
   }
 
+  /// Gets the list of the possible package types.
   pub fn all() -> &'static [PackageType] {
     ALL_PACKAGE_TYPES
   }
@@ -72,84 +84,180 @@ const ALL_PACKAGE_TYPES: &[PackageType] = &[
   PackageType::AppImage,
 ];
 
+/// The build artifact we're bundling.
 #[derive(Clone, Debug)]
 pub enum BuildArtifact {
+  /// The main application.
   Main,
+  /// A named binary which is inside of the [bin] section of your Cargo.toml.
   Bin(String),
+  /// An example app of your crate.
   Example(String),
 }
 
+/// The bundle settings of the BuildArtifact we're bundling.
 #[derive(Clone, Debug, Deserialize, Default)]
 struct BundleSettings {
   // General settings:
+  /// the name of the bundle.
   name: Option<String>,
+  /// the app's identifier.
   identifier: Option<String>,
+  /// the app's icon list.
   icon: Option<Vec<String>>,
+  /// the app's version.
   version: Option<String>,
+  /// the app's resources to bundle.
+  ///
+  /// each item can be a path to a file or a path to a folder.
+  ///
+  /// supports glob patterns.
   resources: Option<Vec<String>>,
+  /// the app's copyright.
   copyright: Option<String>,
+  /// the app's category.
   category: Option<AppCategory>,
+  /// the app's short description.
   short_description: Option<String>,
+  /// the app's long description.
   long_description: Option<String>,
+  /// the app's script to run when unpackaging the bundle.
   script: Option<PathBuf>,
   // OS-specific settings:
+  /// the list of debian dependencies.
   deb_depends: Option<Vec<String>>,
+  /// whether we should use the bootstrap script on debian or not.
+  ///
+  /// this script goal is to allow your app to access environment variables e.g $PATH.
+  ///
+  /// without it, you can't run some applications installed by the user.
   deb_use_bootstrapper: Option<bool>,
+  /// Mac OS X frameworks that need to be bundled with the app.
+  ///
+  /// Each string can either be the name of a framework (without the `.framework` extension, e.g. `"SDL2"`),
+  /// in which case we will search for that framework in the standard install locations (`~/Library/Frameworks/`, `/Library/Frameworks/`, and `/Network/Library/Frameworks/`),
+  /// or a path to a specific framework bundle (e.g. `./data/frameworks/SDL2.framework`).  Note that this setting just makes tauri-bundler copy the specified frameworks into the OS X app bundle
+  /// (under `Foobar.app/Contents/Frameworks/`); you are still responsible for:
+  ///
+  /// - arranging for the compiled binary to link against those frameworks (e.g. by emitting lines like `cargo:rustc-link-lib=framework=SDL2` from your `build.rs` script)
+  ///
+  /// - embedding the correct rpath in your binary (e.g. by running `install_name_tool -add_rpath "@executable_path/../Frameworks" path/to/binary` after compiling)
   osx_frameworks: Option<Vec<String>>,
+  /// A version string indicating the minimum Mac OS X version that the bundled app supports (e.g. `"10.11"`).
+  /// If you are using this config field, you may also want have your `build.rs` script emit `cargo:rustc-env=MACOSX_DEPLOYMENT_TARGET=10.11`.
   osx_minimum_system_version: Option<String>,
+  /// The path to the LICENSE file for macOS apps.
+  /// Currently only used by the dmg bundle.
   osx_license: Option<String>,
+  /// whether we should use the bootstrap script on macOS .app or not.
+  ///
+  /// this script goal is to allow your app to access environment variables e.g $PATH.
+  ///
+  /// without it, you can't run some applications installed by the user.
   osx_use_bootstrapper: Option<bool>,
   // Bundles for other binaries/examples:
+  /// Configuration map for the possible [bin] apps to bundle.
   bin: Option<HashMap<String, BundleSettings>>,
+  /// Configuration map for the possible example apps to bundle.
   example: Option<HashMap<String, BundleSettings>>,
+  /// External binaries to add to the bundle.
+  ///
+  /// Note that each binary name will have the target platform's target triple appended,
+  /// so if you're bundling the `sqlite3` app, the bundler will look for e.g.
+  /// `sqlite3-x86_64-unknown-linux-gnu` on linux,
+  /// and `sqlite3-x86_64-pc-windows-gnu.exe` on windows.
+  ///
+  /// The possible target triples can be seen by running `$ rustup target list`.
   external_bin: Option<Vec<String>>,
+  /// The exception domain to use on the macOS .app bundle.
+  ///
+  /// This allows communication to the outside world e.g. a web server you're shipping.
   exception_domain: Option<String>,
 }
 
+/// The `metadata` section of the package configuration.
+///
+/// # Example Cargo.toml
+/// ```
+/// [package]
+/// name = "..."
+///
+/// [package.metadata.bundle]
+/// identifier = "..."
+/// ...other properties from BundleSettings
+/// ```
 #[derive(Clone, Debug, Deserialize)]
 struct MetadataSettings {
+  /// the bundle settings of the package.
   bundle: Option<BundleSettings>,
 }
 
+/// The `package` section of the app configuration (read from Cargo.toml).
 #[derive(Clone, Debug, Deserialize)]
 struct PackageSettings {
+  /// the package's name.
   name: String,
+  /// the package's version.
   version: String,
+  /// the package's description.
   description: String,
+  /// the package's homepage.
   homepage: Option<String>,
+  /// the package's authors.
   authors: Option<Vec<String>>,
+  /// the package's metadata.
   metadata: Option<MetadataSettings>,
 }
 
+/// The `workspace` section of the app configuration (read from Cargo.toml).
 #[derive(Clone, Debug, Deserialize)]
 struct WorkspaceSettings {
+  /// the workspace members.
   members: Option<Vec<String>>,
 }
 
+/// The Cargo settings (Cargo.toml root descriptor).
 #[derive(Clone, Debug, Deserialize)]
 struct CargoSettings {
-  package: Option<PackageSettings>, // "Ancestor" workspace Cargo.toml files may not have package info
-  workspace: Option<WorkspaceSettings>, // "Ancestor" workspace Cargo.toml files may declare workspaces
+  /// the package settings.
+  ///
+  /// it's optional because ancestor workspace Cargo.toml files may not have package info.
+  package: Option<PackageSettings>,
+  /// the workspace settings.
+  ///
+  /// it's present if the read Cargo.toml belongs to a workspace root.
+  workspace: Option<WorkspaceSettings>,
 }
 
+/// The Settings exposed by the module.
 #[derive(Clone, Debug)]
 pub struct Settings {
+  /// the package settings.
   package: PackageSettings,
-  package_types: Option<Vec<PackageType>>, // If `None`, use the default package type for this os
+  /// the package types we're bundling.
+  ///
+  /// if not present, we'll use the PackageType list for the target OS.
+  package_types: Option<Vec<PackageType>>,
+  /// the target platform of the build
   target: Option<(String, TargetInfo)>,
+  /// the features to use to build the app with `cargo build --features foo bar`.
   features: Option<Vec<String>>,
+  /// the directory where the bundles will be placed.
   project_out_directory: PathBuf,
+  /// the type of build artifact we're bundling.
   build_artifact: BuildArtifact,
+  /// whether we should build the app with release mode or not.
   is_release: bool,
+  /// the path to the binary (project_out_directory + bin_name).
   binary_path: PathBuf,
+  /// the binary name we're bundling.
   binary_name: String,
+  /// the bundle settings.
   bundle_settings: BundleSettings,
 }
 
 impl CargoSettings {
-  /*
-      Try to load a set of CargoSettings from a "Cargo.toml" file in the specified directory
-  */
+  /// Try to load a set of CargoSettings from a "Cargo.toml" file in the specified directory.
   fn load(dir: &PathBuf) -> crate::Result<Self> {
     let toml_path = dir.join("Cargo.toml");
     let mut toml_str = String::new();
@@ -160,6 +268,11 @@ impl CargoSettings {
 }
 
 impl Settings {
+  /// Builds a Settings from the CLI args.
+  ///
+  /// Package settings will be read from Cargo.toml.
+  ///
+  /// Bundle settings will be read from from $TAURI_DIR/tauri.conf.json if it exists and fallback to Cargo.toml's [package.metadata.bundle].
   pub fn new(current_dir: PathBuf, matches: &ArgMatches<'_>) -> crate::Result<Self> {
     let package_types = match matches.values_of("format") {
       Some(names) => {
@@ -258,7 +371,7 @@ impl Settings {
     };
     let binary_path = target_dir.join(&binary_name);
 
-    let bundle_settings = add_external_bin(bundle_settings)?;
+    let bundle_settings = parse_external_bin(bundle_settings)?;
 
     Ok(Settings {
       package,
@@ -274,16 +387,8 @@ impl Settings {
     })
   }
 
-  /*
-      The target_dir where binaries will be compiled to by cargo can vary:
-          - this directory is a member of a workspace project
-          - overridden by CARGO_TARGET_DIR environment variable
-          - specified in build.target-dir configuration key
-          - if the build is a 'release' or 'debug' build
-
-      This function determines where 'target' dir is and suffixes it with 'release' or 'debug'
-      to determine where the compiled binary will be located.
-  */
+  /// This function determines where 'target' dir is and suffixes it with 'release' or 'debug'
+  /// to determine where the compiled binary will be located.
   fn get_target_dir(
     project_root_dir: &PathBuf,
     target: &Option<(String, TargetInfo)>,
@@ -301,16 +406,11 @@ impl Settings {
     path
   }
 
-  /*
-      The specification of the Cargo.toml Manifest that covers the "workspace" section is here:
-      https://doc.rust-lang.org/cargo/reference/manifest.html#the-workspace-section
-
-      Determining if the current project folder is part of a workspace:
-          - Walk up the file system, looking for a Cargo.toml file.
-          - Stop at the first one found.
-          - If one is found before reaching "/" then this folder belongs to that parent workspace,
-            if it contains a [workspace] entry and the project crate name is listed on the "members" array
-  */
+  /// Walks up the file system, looking for a Cargo.toml file
+  /// If one is found before reaching the root, then the current_dir's package belongs to that parent workspace if it's listed on [workspace.members].
+  ///
+  /// If this package is part of a workspace, returns the path to the workspace directory
+  /// Otherwise returns the current directory.
   pub fn get_workspace_dir(current_dir: &PathBuf) -> PathBuf {
     let mut dir = current_dir.clone();
     let project_name = CargoSettings::load(&dir).unwrap().package.unwrap().name;
@@ -344,8 +444,7 @@ impl Settings {
     &self.project_out_directory
   }
 
-  /// Returns the architecture for the binary being bundled (e.g. "arm" or
-  /// "x86" or "x86_64").
+  /// Returns the architecture for the binary being bundled (e.g. "arm", "x86" or "x86_64").
   pub fn binary_arch(&self) -> &str {
     if let Some((_, ref info)) = self.target {
       info.target_arch()
@@ -365,10 +464,13 @@ impl Settings {
   }
 
   /// If a list of package types was specified by the command-line, returns
-  /// that list filtered by the current target's available targets;
-  /// otherwise, if a target triple was specified by the
-  /// command-line, returns the native package type(s) for that target;
-  /// otherwise, returns the native package type(s) for the host platform.
+  /// that list filtered by the current target OS available targets.
+  ///
+  /// If a target triple was specified by the
+  /// command-line, returns the native package type(s) for that target.
+  ///
+  /// Otherwise returns the native package type(s) for the host platform.
+  ///
   /// Fails if the host/target's native package type is not supported.
   pub fn package_types(&self) -> crate::Result<Vec<PackageType>> {
     let target_os = if let Some((_, ref info)) = self.target {
@@ -408,7 +510,7 @@ impl Settings {
   }
 
   /// If the bundle is being cross-compiled, returns the target triple string
-  /// (e.g. `"x86_64-apple-darwin"`).  If the bundle is targeting the host
+  /// (e.g. `"x86_64-apple-darwin"`). If the bundle is targeting the host
   /// environment, returns `None`.
   pub fn target_triple(&self) -> Option<&str> {
     match self.target {
@@ -433,6 +535,7 @@ impl Settings {
     self.is_release
   }
 
+  /// Returns the bundle name, which is either package.metadata.bundle.name or package.name
   pub fn bundle_name(&self) -> &str {
     self
       .bundle_settings
@@ -441,6 +544,7 @@ impl Settings {
       .unwrap_or(&self.package.name)
   }
 
+  /// Returns the bundle's identifier
   pub fn bundle_identifier(&self) -> &str {
     self
       .bundle_settings
@@ -476,11 +580,12 @@ impl Settings {
     }
   }
 
+  /// Returns the OSX exception domain.
   pub fn exception_domain(&self) -> Option<&String> {
     self.bundle_settings.exception_domain.as_ref()
   }
 
-  // copy external binaries to a path.
+  /// Copies external binaries to a path.
   pub fn copy_binaries(&self, path: &Path) -> crate::Result<()> {
     for src in self.external_binaries() {
       let src = src?;
@@ -494,7 +599,7 @@ impl Settings {
     Ok(())
   }
 
-  // copy resources to a path
+  /// Copies resources to a path.
   pub fn copy_resources(&self, path: &Path) -> crate::Result<()> {
     for src in self.resource_files() {
       let src = src?;
@@ -504,6 +609,7 @@ impl Settings {
     Ok(())
   }
 
+  /// Returns the version string of the bundle, which is either package.metadata.version or package.version.
   pub fn version_string(&self) -> &str {
     self
       .bundle_settings
@@ -512,10 +618,12 @@ impl Settings {
       .unwrap_or(&self.package.version)
   }
 
+  /// Returns the copyright text.
   pub fn copyright_string(&self) -> Option<&str> {
     self.bundle_settings.copyright.as_ref().map(String::as_str)
   }
 
+  /// Returns the list of authors name.
   pub fn author_names(&self) -> &[String] {
     match self.package.authors {
       Some(ref names) => names.as_slice(),
@@ -523,6 +631,7 @@ impl Settings {
     }
   }
 
+  /// Returns the authors as a comma-separated string.
   pub fn authors_comma_separated(&self) -> Option<String> {
     let names = self.author_names();
     if names.is_empty() {
@@ -532,6 +641,7 @@ impl Settings {
     }
   }
 
+  /// Returns the package's homepage URL, defaulting to "" if not defined.
   pub fn homepage_url(&self) -> &str {
     &self
       .package
@@ -541,10 +651,12 @@ impl Settings {
       .unwrap_or("")
   }
 
+  /// Returns the app's category.
   pub fn app_category(&self) -> Option<AppCategory> {
     self.bundle_settings.category
   }
 
+  /// Returns the app's short description.
   pub fn short_description(&self) -> &str {
     self
       .bundle_settings
@@ -553,6 +665,7 @@ impl Settings {
       .unwrap_or(&self.package.description)
   }
 
+  /// Returns the app's long description.
   pub fn long_description(&self) -> Option<&str> {
     self
       .bundle_settings
@@ -561,6 +674,7 @@ impl Settings {
       .map(String::as_str)
   }
 
+  /// Returns the dependencies of the debian bundle.
   pub fn debian_dependencies(&self) -> &[String] {
     match self.bundle_settings.deb_depends {
       Some(ref dependencies) => dependencies.as_slice(),
@@ -568,10 +682,12 @@ impl Settings {
     }
   }
 
+  /// Returns whether the debian bundle should use the bootstrap script or not.
   pub fn debian_use_bootstrapper(&self) -> bool {
     self.bundle_settings.deb_use_bootstrapper.unwrap_or(false)
   }
 
+  /// Returns the frameworks to bundle with the macOS .app
   pub fn osx_frameworks(&self) -> &[String] {
     match self.bundle_settings.osx_frameworks {
       Some(ref frameworks) => frameworks.as_slice(),
@@ -579,6 +695,7 @@ impl Settings {
     }
   }
 
+  /// Returns the minimum system version of the macOS bundle.
   pub fn osx_minimum_system_version(&self) -> Option<&str> {
     self
       .bundle_settings
@@ -587,6 +704,7 @@ impl Settings {
       .map(String::as_str)
   }
 
+  /// Returns the path to the DMG bundle license.
   pub fn osx_license(&self) -> Option<&str> {
     self
       .bundle_settings
@@ -595,11 +713,14 @@ impl Settings {
       .map(String::as_str)
   }
 
+  /// Returns whether the macOS .app bundle should use the bootstrap script or not.
   pub fn osx_use_bootstrapper(&self) -> bool {
     self.bundle_settings.osx_use_bootstrapper.unwrap_or(false)
   }
 }
 
+/// Gets the bundle settings from a map.
+/// It can be used to get the bundle settings from the [example] or [bin] section of Cargo.toml
 fn bundle_settings_from_table(
   opt_map: &Option<HashMap<String, BundleSettings>>,
   map_name: &str,
@@ -615,7 +736,8 @@ fn bundle_settings_from_table(
   }
 }
 
-fn add_external_bin(bundle_settings: BundleSettings) -> crate::Result<BundleSettings> {
+/// Parses the external binaries to bundle, adding the target triple suffix to each of them.
+fn parse_external_bin(bundle_settings: BundleSettings) -> crate::Result<BundleSettings> {
   let target_triple = target_triple()?;
   let mut win_paths = Vec::new();
   let external_bin = match bundle_settings.external_bin {
@@ -639,6 +761,7 @@ fn add_external_bin(bundle_settings: BundleSettings) -> crate::Result<BundleSett
   })
 }
 
+/// Returns the first Option with a value, or None if both are None.
 fn options_value<T>(first: Option<T>, second: Option<T>) -> Option<T> {
   if let Some(_) = first {
     first
@@ -647,6 +770,7 @@ fn options_value<T>(first: Option<T>, second: Option<T>) -> Option<T> {
   }
 }
 
+/// Merges the bundle settings from Cargo.toml and tauri.conf.json
 fn merge_settings(
   bundle_settings: BundleSettings,
   config: crate::bundle::tauri_config::BundleConfig,
@@ -680,16 +804,24 @@ fn merge_settings(
   }
 }
 
+/// A helper to iterate through resources.
 pub struct ResourcePaths<'a> {
+  /// the patterns to iterate.
   pattern_iter: std::slice::Iter<'a, String>,
+  /// the glob iterator if the path from the current iteration is a glob pattern.
   glob_iter: Option<glob::Paths>,
+  /// the walkdir iterator if the path from the current iteration is a directory.
   walk_iter: Option<walkdir::IntoIter>,
+  /// whether the resource paths allows directories or not.
   allow_walk: bool,
+  /// the pattern of the current iteration.
   current_pattern: Option<String>,
+  /// whether the current pattern is valid or not.
   current_pattern_is_valid: bool,
 }
 
 impl<'a> ResourcePaths<'a> {
+  /// Creates a new ResourcePaths from a slice of patterns to iterate
   fn new(patterns: &'a [String], allow_walk: bool) -> ResourcePaths<'a> {
     ResourcePaths {
       pattern_iter: patterns.iter(),

+ 31 - 11
cli/tauri-bundler/src/bundle/wix.rs

@@ -35,7 +35,7 @@ pub const WIX_SHA256: &str = "2c1888d5d1dba377fc7fa14444cf556963747ff9a0a289a359
 // const VC_REDIST_X64_SHA256: &str =
 //   "d6cd2445f68815fe02489fafe0127819e44851e26dfbe702612bc0d223cbbc2b";
 
-// A v4 UUID that was generated specifically for cargo-bundle, to be used as a
+// A v4 UUID that was generated specifically for tauri-bundler, to be used as a
 // namespace for generating v5 UUIDs from bundle identifier strings.
 const UUID_NAMESPACE: [u8; 16] = [
   0xfd, 0x85, 0x95, 0xa8, 0x17, 0xa3, 0x47, 0x4e, 0xa6, 0x16, 0x76, 0x14, 0x8d, 0xfa, 0x0c, 0x7b,
@@ -54,35 +54,52 @@ lazy_static! {
   };
 }
 
+/// Mapper between a resource directory name and its ResourceDirectory descriptor.
 type ResourceMap = BTreeMap<String, ResourceDirectory>;
 
+/// An external binary to bundle with WIX.
+/// This data structure is needed because WIX requires each path to have its own `id` and `guid`.
 #[derive(Serialize)]
 struct ExternalBinary {
+  /// the GUID to use on the WIX XML.
   guid: String,
+  /// the id to use on the WIX XML.
   id: String,
+  /// the external binary path.
   path: String,
 }
 
+/// A Resource file to bundle with WIX.
+/// This data structure is needed because WIX requires each path to have its own `id` and `guid`.
 #[derive(Serialize, Clone)]
 struct ResourceFile {
+  /// the GUID to use on the WIX XML.
   guid: String,
+  /// the id to use on the WIX XML.
   id: String,
+  /// the file path.
   path: String,
 }
 
+/// A resource directory to bundle with WIX.
+/// This data structure is needed because WIX requires each path to have its own `id` and `guid`.
 #[derive(Serialize)]
 struct ResourceDirectory {
+  /// the directory name of the described resource.
   name: String,
+  /// the files of the described resource directory.
   files: Vec<ResourceFile>,
+  /// the directories that are children of the described resource directory.
   directories: Vec<ResourceDirectory>,
 }
 
 impl ResourceDirectory {
+  /// Adds a file to this directory descriptor.
   fn add_file(&mut self, file: ResourceFile) {
     self.files.push(file);
   }
 
-  // generates the wix XML string to bundle this directory resources recursively
+  /// Generates the wix XML string to bundle this directory resources recursively
   fn get_wix_data(self) -> crate::Result<(String, Vec<String>)> {
     let mut files = String::from("");
     let mut file_ids = Vec::new();
@@ -115,6 +132,8 @@ impl ResourceDirectory {
   }
 }
 
+/// Copies the icons to the binary path, under the `resources` folder,
+/// and returns the path to that directory.
 fn copy_icons(settings: &Settings) -> crate::Result<PathBuf> {
   let base_dir = settings.binary_path();
   let base_dir = base_dir.parent().expect("Failed to get dir");
@@ -144,7 +163,7 @@ fn copy_icons(settings: &Settings) -> crate::Result<PathBuf> {
   Ok(resource_dir)
 }
 
-// Function used to download Wix and VC_REDIST. Checks SHA256 to verify the download.
+/// Function used to download Wix and VC_REDIST. Checks SHA256 to verify the download.
 fn download_and_verify(url: &str, hash: &str) -> crate::Result<Vec<u8>> {
   common::print_info(format!("Downloading {}", url).as_str())?;
 
@@ -167,6 +186,7 @@ fn download_and_verify(url: &str, hash: &str) -> crate::Result<Vec<u8>> {
   }
 }
 
+/// The installer directory of the app.
 fn app_installer_dir(settings: &Settings) -> crate::Result<PathBuf> {
   let arch = match settings.binary_arch() {
     "x86" => "x86",
@@ -186,7 +206,7 @@ fn app_installer_dir(settings: &Settings) -> crate::Result<PathBuf> {
   )))
 }
 
-// Extracts the zips from Wix and VC_REDIST into a useable path.
+/// Extracts the zips from Wix and VC_REDIST into a useable path.
 fn extract_zip(data: &Vec<u8>, path: &Path) -> crate::Result<()> {
   let cursor = Cursor::new(data);
 
@@ -211,18 +231,18 @@ fn extract_zip(data: &Vec<u8>, path: &Path) -> crate::Result<()> {
   Ok(())
 }
 
-// Generates the UUID for the Wix template.
+/// Generates the UUID for the Wix template.
 fn generate_package_guid(settings: &Settings) -> Uuid {
   generate_guid(settings.bundle_identifier().as_bytes())
 }
 
+/// Generates a GUID.
 fn generate_guid(key: &[u8]) -> Uuid {
   let namespace = Uuid::from_bytes(UUID_NAMESPACE);
   Uuid::new_v5(&namespace, key)
 }
 
 // Specifically goes and gets Wix and verifies the download via Sha256
-
 pub fn get_and_extract_wix(path: &Path) -> crate::Result<()> {
   common::print_info("Verifying wix package")?;
 
@@ -285,7 +305,7 @@ pub fn get_and_extract_wix(path: &Path) -> crate::Result<()> {
 //   }
 // }
 
-// Runs the Candle.exe executable for Wix.  Candle parses the wxs file and generates the code for building the installer.
+/// Runs the Candle.exe executable for Wix. Candle parses the wxs file and generates the code for building the installer.
 fn run_candle(
   settings: &Settings,
   wix_toolset_path: &Path,
@@ -336,7 +356,7 @@ fn run_candle(
   }
 }
 
-// Runs the Light.exe file.  Light takes the generated code from Candle and produces an MSI Installer.
+/// Runs the Light.exe file. Light takes the generated code from Candle and produces an MSI Installer.
 fn run_light(
   wix_toolset_path: &Path,
   build_path: &Path,
@@ -385,7 +405,7 @@ fn run_light(
 //   Ok(())
 // }
 
-// Entry point for bundling and creating the MSI installer.  For now the only supported platform is Windows x64.
+// Entry point for bundling and creating the MSI installer. For now the only supported platform is Windows x64.
 pub fn build_wix_app_installer(
   settings: &Settings,
   wix_toolset_path: &Path,
@@ -401,7 +421,6 @@ pub fn build_wix_app_installer(
     }
   };
 
-  // common::print_warning("Only x64 supported")?;
   // target only supports x64.
   common::print_info(format!("Target: {}", arch).as_str())?;
 
@@ -489,6 +508,7 @@ pub fn build_wix_app_installer(
   Ok(target)
 }
 
+/// Generates the data required for the external binaries bundling.
 fn generate_external_binary_data(settings: &Settings) -> crate::Result<Vec<ExternalBinary>> {
   let mut external_binaries = Vec::new();
   let regex = Regex::new(r"[^\w\d\.]")?;
@@ -518,7 +538,7 @@ fn generate_external_binary_data(settings: &Settings) -> crate::Result<Vec<Exter
   Ok(external_binaries)
 }
 
-// generates the data required for the resource bundling on wix
+/// Generates the data required for the resource bundling on wix
 fn generate_resource_data(settings: &Settings) -> crate::Result<ResourceMap> {
   let mut resources = ResourceMap::new();
   let regex = Regex::new(r"[^\w\d\.]")?;

+ 2 - 1
cli/tauri-bundler/src/main.rs

@@ -13,7 +13,7 @@ use runas::Command;
 use std::env;
 use std::process;
 
-/// Runs `cargo build` to make sure the binary file is up-to-date.
+// Runs `cargo build` to make sure the binary file is up-to-date.
 fn build_project_if_unbuilt(settings: &Settings) -> crate::Result<()> {
   let mut args = vec!["build".to_string()];
   if let Some(triple) = settings.target_triple() {
@@ -49,6 +49,7 @@ fn build_project_if_unbuilt(settings: &Settings) -> crate::Result<()> {
   Ok(())
 }
 
+// Runs the CLI.
 fn run() -> crate::Result<()> {
   let all_formats: Vec<&str> = PackageType::all()
     .iter()

+ 189 - 0
cli/tauri.js/src/types/config.ts

@@ -1,61 +1,250 @@
+/**
+ * A CLI argument definition
+ */
 export interface CliArg {
+  /**
+   * the short version of the argument, without the preceding -
+   * NOTE: Any leading - characters will be stripped, and only the first non - character will be used as the short version
+   */
   short?: string
+  /**
+   * the unique argument name
+   */
   name: string
+  /**
+   * the argument description which will be shown on the help information
+   * typically, this is a short (one line) description of the arg
+   */
   description?: string
+  /**
+   * the argument long description which will be shown on the help information
+   * typically this a more detailed (multi-line) message that describes the argument
+   */
   longDescription?: string
+  /**
+   * specifies that the argument takes a value at run time.
+   * NOTE: values for arguments may be specified in any of the following methods
+   * - Using a space such as -o value or --option value
+   * - Using an equals and no space such as -o=value or --option=value
+   * - Use a short and no space such as -ovalue
+   */
   takesValue?: boolean
+  /**
+   * specifies that the argument may appear more than once.
+   * for flags, this results in the number of occurrences of the flag being recorded. For example -ddd or -d -d -d would count as three occurrences.
+   * for options there is a distinct difference in multiple occurrences vs multiple values. For example, --opt val1 val2 is one occurrence, but two values. Whereas --opt val1 --opt val2 is two occurrences.
+   */
   multiple?: boolean
+  /**
+   * specifies a list of possible values for this argument. At runtime, the CLI verifies that only one of the specified values was used, or fails with an error message.
+   */
   possibleValues?: string[]
+  /**
+   * specifies the minimum number of values for this argument.
+   * for example, if you had a -f <file> argument where you wanted at least 2 'files' you would set `minValues: 2`, and this argument would be satisfied if the user provided, 2 or more values.
+   */
   minValues?: number
+  /**
+   * specifies the maximum number of values are for this argument.
+   * for example, if you had a -f <file> argument where you wanted up to 3 'files' you would set .max_values(3), and this argument would be satisfied if the user provided, 1, 2, or 3 values.
+   */
   maxValues?: number
+  /**
+   * sets whether or not the argument is required by default
+   * required by default means it is required, when no other conflicting rules have been evaluated
+   * conflicting rules take precedence over being required.
+   */
   required?: boolean
+  /**
+   * sets an arg that override this arg's required setting
+   * i.e. this arg will be required unless this other argument is present
+   */
   requiredUnless?: string
+  /**
+   * sets args that override this arg's required setting
+   * i.e. this arg will be required unless all these other arguments are present
+   */
   requiredUnlessAll?: string[]
+  /**
+   * sets args that override this arg's required setting
+   * i.e. this arg will be required unless at least one of these other arguments are present
+   */
   requiredUnlessOne?: string[]
+  /**
+   * sets a conflicting argument by name
+   * i.e. when using this argument, the following argument can't be present and vice versa
+   */
   conflictsWith?: string
+  /**
+   * the same as conflictsWith but allows specifying multiple two-way conflicts per argument
+   */
   conflictsWithAll?: string
+  /**
+   * sets an argument by name that is required when this one is present
+   * i.e. when using this argument, the following argument must be present
+   */
   requires?: string
+  /**
+   * sets multiple arguments by names that are required when this one is present
+   * i.e. when using this argument, the following arguments must be present
+   */
   requiresAll?: string[]
+  /**
+   * allows a conditional requirement with the signature [arg: string, value: string]
+   * the requirement will only become valid if `arg`'s value equals `${value}`
+   */
   requiresIf?: [string, string]
+  /**
+   * allows specifying that an argument is required conditionally with the signature [arg: string, value: string]
+   * the requirement will only become valid if the `arg`'s value equals `${value}`.
+   */
   requiredIf?: [string, string]
+  /**
+   * requires that options use the --option=val syntax
+   * i.e. an equals between the option and associated value
+   */
   requireEquals?: boolean
+  /**
+   * The positional argument index, starting at 1.
+   *
+   * The index refers to position according to other positional argument.
+   * It does not define position in the argument list as a whole. When utilized with multiple=true,
+   * only the last positional argument may be defined as multiple (i.e. the one with the highest index).
+   */
   index?: number
 }
 
+/**
+ * describes a CLI configuration
+ */
 export interface CliConfig {
+  /**
+   * list of args for the command
+   */
   args?: CliArg[]
+  /**
+   * command description which will be shown on the help information
+   */
   description?: string
+  /**
+   * command long description which will be shown on the help information
+   */
   longDescription?: string
+  /**
+   * adds additional help information to be displayed in addition to auto-generated help
+   * this information is displayed before the auto-generated help information.
+   * this is often used for header information
+   */
   beforeHelp?: string
+  /**
+   * adds additional help information to be displayed in addition to auto-generated help
+   * this information is displayed after the auto-generated help information
+   * this is often used to describe how to use the arguments, or caveats to be noted.
+   */
   afterHelp?: string
+  /**
+   * list of subcommands of this command
+   *
+   * subcommands are effectively sub-apps, because they can contain their own arguments, subcommands, usage, etc.
+   * they also function just like the app command, in that they get their own auto generated help and usage
+   */
   subcommands?: { [name: string]: CliConfig }
 }
 
+/**
+ * Tauri configuration
+ */
 export interface TauriConfig {
+  /**
+   * build/dev configuration
+   */
   build: {
+    /**
+     * the path to the app's dist dir
+     * this path must contain your index.html file
+     */
     distDir: string
+    /**
+     * the app's dev server URL, or the path to the directory containing an index.html to open
+     */
     devPath: string
+    /**
+     * a shell command to run before `tauri dev` kicks in
+     */
     beforeDevCommand?: string
+    /**
+     * a shell command to run before `tauri build` kicks in
+     */
     beforeBuildCommand?: string
     withGlobalTauri?: boolean
   }
+  /**
+   * the context of the current `tauri dev` or `tauri build`
+   */
   ctx: {
+    /**
+     * whether we're building for production or not
+     */
     prod?: boolean
+    /**
+     * whether we're running on the dev environment or not
+     */
     dev?: boolean
+    /**
+     * the target of the compilation (see `rustup target list`)
+     */
     target?: string
+    /**
+     * whether the app should be built on debug mode or not
+     */
     debug?: boolean
+    /**
+     * defines we should exit the `tauri dev` process if a Rust code error is found
+     */
     exitOnPanic?: boolean
   }
+  /**
+   * tauri root configuration object
+   */
   tauri: {
+    /**
+     * app's CLI definition
+     */
     cli?: CliConfig
+    /**
+     * the embedded server configuration
+     */
     embeddedServer: {
+      /**
+       * whether we should use the embedded-server or the no-server mode
+       */
       active?: boolean
     }
+    /**
+     * tauri bundler configuration
+     */
     bundle: {
+      /**
+       * whether we should build your app with tauri-bundler or plain `cargo build`
+       */
       active?: boolean
+      /**
+       * the bundle targets, currently supports ["deb", "osx", "msi", "appimage", "dmg"] or "all"
+       */
       targets?: string | string[]
+      /**
+       * the app's identifier
+       */
       identifier: string
+      /**
+       * the app's icons
+       */
       icon: string[]
+      /**
+       * app resources to bundle
+       * each resource is a path to a file or directory
+       * glob patterns are supported
+       */
       resources?: string[]
       externalBin?: string[]
       copyright?: string

+ 27 - 4
tauri-api/src/cli.rs

@@ -1,4 +1,4 @@
-use crate::config::{get as get_config, Cli};
+use crate::config::{get as get_config, CliConfig};
 
 use clap::{App, Arg, ArgMatches};
 use serde::Serialize;
@@ -8,34 +8,51 @@ use std::collections::HashMap;
 #[macro_use]
 mod macros;
 
+/// The resolution of a arg match.
 #[derive(Default, Debug, Serialize)]
 pub struct ArgData {
+  /// The value of the arg.
+  /// - Value::Bool if it's a flag,
+  /// - Value::Array if it's multiple,
+  /// - Value::String if it has value,
+  /// - Value::Null otherwise.
   value: Value,
+  /// The number of occurrences of the arg.
+  /// e.g. `./app --arg 1 --arg 2 --arg 2 3 4` results in three occurrences.
   occurrences: u64,
 }
 
+/// The matched subcommand.
 #[derive(Default, Debug, Serialize)]
 pub struct SubcommandMatches {
+  /// The subcommand name.
   name: String,
+  /// The subcommand arg matches.
   matches: Matches,
 }
 
+/// The arg matches of a command.
 #[derive(Default, Debug, Serialize)]
 pub struct Matches {
+  /// Data structure mapping each found arg with its resolution.
   args: HashMap<String, ArgData>,
+  /// The matched subcommand if found.
   subcommand: Option<Box<SubcommandMatches>>,
 }
 
 impl Matches {
+  /// Set a arg match.
   pub(crate) fn set_arg(&mut self, name: String, value: ArgData) {
     self.args.insert(name, value);
   }
 
+  /// Sets the subcommand matches.
   pub(crate) fn set_subcommand(&mut self, name: String, matches: Matches) {
     self.subcommand = Some(Box::new(SubcommandMatches { name, matches }));
   }
 }
 
+/// Gets the arg matches of the CLI definition.
 pub fn get_matches() -> crate::Result<Matches> {
   let config = get_config()?;
   let cli = config
@@ -53,7 +70,7 @@ pub fn get_matches() -> crate::Result<Matches> {
   Ok(get_matches_internal(cli, &matches))
 }
 
-fn get_matches_internal<T: Cli + 'static>(config: &T, matches: &ArgMatches) -> Matches {
+fn get_matches_internal(config: &CliConfig, matches: &ArgMatches) -> Matches {
   let mut cli_matches = Matches::default();
   map_matches(config, matches, &mut cli_matches);
 
@@ -71,7 +88,7 @@ fn get_matches_internal<T: Cli + 'static>(config: &T, matches: &ArgMatches) -> M
   cli_matches
 }
 
-fn map_matches<T: Cli + 'static>(config: &T, matches: &ArgMatches, cli_matches: &mut Matches) {
+fn map_matches(config: &CliConfig, matches: &ArgMatches, cli_matches: &mut Matches) {
   if let Some(args) = config.args() {
     for arg in args {
       let occurrences = matches.occurrences_of(arg.name.clone());
@@ -100,7 +117,7 @@ fn map_matches<T: Cli + 'static>(config: &T, matches: &ArgMatches, cli_matches:
   }
 }
 
-fn get_app<'a, T: Cli + 'static>(name: &str, about: Option<&'a String>, config: &'a T) -> App<'a> {
+fn get_app<'a>(name: &str, about: Option<&'a String>, config: &'a CliConfig) -> App<'a> {
   let mut app = App::new(name)
     .author(crate_authors!())
     .version(crate_version!());
@@ -111,6 +128,12 @@ fn get_app<'a, T: Cli + 'static>(name: &str, about: Option<&'a String>, config:
   if let Some(long_description) = config.long_description() {
     app = app.long_about(&**long_description);
   }
+  if let Some(before_help) = config.before_help() {
+    app = app.before_help(&**before_help);
+  }
+  if let Some(after_help) = config.after_help() {
+    app = app.after_help(&**after_help);
+  }
 
   if let Some(args) = config.args() {
     for arg in args {

+ 11 - 44
tauri-api/src/command.rs

@@ -8,6 +8,7 @@ const CREATE_NO_WINDOW: u32 = 0x08000000;
 
 use tauri_utils::platform;
 
+/// Gets the output of the given command.
 #[cfg(not(windows))]
 pub fn get_output(cmd: String, args: Vec<String>, stdout: Stdio) -> crate::Result<String> {
   let output = Command::new(cmd).args(args).stdout(stdout).output()?;
@@ -19,6 +20,7 @@ pub fn get_output(cmd: String, args: Vec<String>, stdout: Stdio) -> crate::Resul
   }
 }
 
+/// Gets the output of the given command.
 #[cfg(windows)]
 pub fn get_output(cmd: String, args: Vec<String>, stdout: Stdio) -> crate::Result<String> {
   let output = Command::new(cmd)
@@ -34,21 +36,7 @@ pub fn get_output(cmd: String, args: Vec<String>, stdout: Stdio) -> crate::Resul
   }
 }
 
-pub fn format_command(path: String, command: String) -> String {
-  if cfg!(windows) {
-    format!("{}/./{}.exe", path, command)
-  } else {
-    format!("{}/./{}", path, command)
-  }
-}
-
-pub fn relative_command(command: String) -> crate::Result<String> {
-  match std::env::current_exe()?.parent() {
-    Some(exe_dir) => Ok(format_command(exe_dir.display().to_string(), command)),
-    None => Err(crate::Error::Command("Could not evaluate executable dir".to_string()).into()),
-  }
-}
-
+/// Gets the path to command relative to the current executable path.
 #[cfg(not(windows))]
 pub fn command_path(command: String) -> crate::Result<String> {
   match std::env::current_exe()?.parent() {
@@ -57,6 +45,7 @@ pub fn command_path(command: String) -> crate::Result<String> {
   }
 }
 
+/// Gets the path to command relative to the current executable path.
 #[cfg(windows)]
 pub fn command_path(command: String) -> crate::Result<String> {
   match std::env::current_exe()?.parent() {
@@ -65,13 +54,15 @@ pub fn command_path(command: String) -> crate::Result<String> {
   }
 }
 
+/// Spawns a process with a command string relative to the current executable path.
+/// For example, if your app bundles two executables, you don't need to worry about its path and just run `second-app`.
 #[cfg(windows)]
 pub fn spawn_relative_command(
   command: String,
   args: Vec<String>,
   stdout: Stdio,
 ) -> crate::Result<Child> {
-  let cmd = relative_command(command)?;
+  let cmd = command_path(command)?;
   Ok(
     Command::new(cmd)
       .args(args)
@@ -81,16 +72,19 @@ pub fn spawn_relative_command(
   )
 }
 
+/// Spawns a process with a command string relative to the current executable path.
+/// For example, if your app bundles two executables, you don't need to worry about its path and just run `second-app`.
 #[cfg(not(windows))]
 pub fn spawn_relative_command(
   command: String,
   args: Vec<String>,
   stdout: Stdio,
 ) -> crate::Result<Child> {
-  let cmd = relative_command(command)?;
+  let cmd = command_path(command)?;
   Ok(Command::new(cmd).args(args).stdout(stdout).spawn()?)
 }
 
+/// Gets the binary command with the current target triple.
 pub fn binary_command(binary_name: String) -> crate::Result<String> {
   Ok(format!("{}-{}", binary_name, platform::target_triple()?))
 }
@@ -141,33 +135,6 @@ mod test {
     }
   }
 
-  #[test]
-  // test the relative_command function
-  fn check_relateive_cmd() {
-    // generate a cat string
-    let cmd = String::from("cat");
-
-    // call relative command on the cat string
-    let res = relative_command(cmd.clone());
-
-    // assert that the result comes back with Ok()
-    assert_ok!(res);
-
-    // get the parent directory of the current executable.
-    let current_exe = std::env::current_exe()
-      .unwrap()
-      .parent()
-      .unwrap()
-      .display()
-      .to_string();
-
-    // check the string inside of the Ok
-    if let Ok(s) = &res {
-      // match the string against the call to format command with the current_exe.
-      assert_eq!(*s, format_command(current_exe, cmd));
-    }
-  }
-
   #[test]
   // test the command_path function
   fn check_command_path() {

+ 113 - 49
tauri-api/src/config.rs

@@ -5,17 +5,23 @@ use std::collections::HashMap;
 
 static CONFIG: OnceCell<Config> = OnceCell::new();
 
+/// The window configuration object.
 #[derive(PartialEq, Deserialize, Debug)]
 #[serde(tag = "window", rename_all = "camelCase")]
 pub struct WindowConfig {
+  /// The window width.
   #[serde(default = "default_width")]
   pub width: i32,
+  /// The window height.
   #[serde(default = "default_height")]
   pub height: i32,
+  /// Whether the window is resizable or not.
   #[serde(default = "default_resizable")]
   pub resizable: bool,
+  /// The window title.
   #[serde(default = "default_title")]
   pub title: String,
+  /// Whether the window starts as fullscreen or not.
   #[serde(default)]
   pub fullscreen: bool,
 }
@@ -46,11 +52,15 @@ fn default_window() -> WindowConfig {
   }
 }
 
+/// The embeddedServer configuration object.
 #[derive(PartialEq, Deserialize, Debug)]
 #[serde(tag = "embeddedServer", rename_all = "camelCase")]
 pub struct EmbeddedServerConfig {
+  /// The embedded server host.
   #[serde(default = "default_host")]
   pub host: String,
+  /// The embedded server port.
+  /// If it's `random`, we'll generate one at runtime.
   #[serde(default = "default_port")]
   pub port: String,
 }
@@ -70,45 +80,94 @@ fn default_embedded_server() -> EmbeddedServerConfig {
   }
 }
 
+/// A CLI argument definition
 #[derive(PartialEq, Deserialize, Debug, Default)]
 #[serde(rename_all = "camelCase")]
 pub struct CliArg {
+  /// The short version of the argument, without the preceding -.
+  ///
+  /// NOTE: Any leading - characters will be stripped, and only the first non - character will be used as the short version.
   pub short: Option<char>,
+  /// The unique argument name
   pub name: String,
+  /// The argument description which will be shown on the help information.
+  /// Typically, this is a short (one line) description of the arg.
   pub description: Option<String>,
+  /// The argument long description which will be shown on the help information.
+  /// Typically this a more detailed (multi-line) message that describes the argument.
   pub long_description: Option<String>,
+  /// Specifies that the argument takes a value at run time.
+  ///
+  /// NOTE: values for arguments may be specified in any of the following methods
+  /// - Using a space such as -o value or --option value
+  /// - Using an equals and no space such as -o=value or --option=value
+  /// - Use a short and no space such as -ovalue
   pub takes_value: Option<bool>,
+  /// Specifies that the argument may appear more than once.
+  ///
+  /// - For flags, this results in the number of occurrences of the flag being recorded.
+  /// For example -ddd or -d -d -d would count as three occurrences.
+  /// - For options there is a distinct difference in multiple occurrences vs multiple values.
+  /// For example, --opt val1 val2 is one occurrence, but two values. Whereas --opt val1 --opt val2 is two occurrences.
   pub multiple: Option<bool>,
+  ///
   pub multiple_occurrences: Option<bool>,
+  ///
   pub number_of_values: Option<u64>,
+  /// Specifies a list of possible values for this argument.
+  /// At runtime, the CLI verifies that only one of the specified values was used, or fails with an error message.
   pub possible_values: Option<Vec<String>>,
+  /// Specifies the minimum number of values for this argument.
+  /// For example, if you had a -f <file> argument where you wanted at least 2 'files',
+  /// you would set `minValues: 2`, and this argument would be satisfied if the user provided, 2 or more values.
   pub min_values: Option<u64>,
+  /// Specifies the maximum number of values are for this argument.
+  /// For example, if you had a -f <file> argument where you wanted up to 3 'files',
+  /// you would set .max_values(3), and this argument would be satisfied if the user provided, 1, 2, or 3 values.
   pub max_values: Option<u64>,
+  /// Sets whether or not the argument is required by default.
+  ///
+  /// - Required by default means it is required, when no other conflicting rules have been evaluated
+  /// - Conflicting rules take precedence over being required.
   pub required: Option<bool>,
+  /// Sets an arg that override this arg's required setting
+  /// i.e. this arg will be required unless this other argument is present.
   pub required_unless: Option<String>,
+  /// Sets args that override this arg's required setting
+  /// i.e. this arg will be required unless all these other arguments are present.
   pub required_unless_all: Option<Vec<String>>,
+  /// Sets args that override this arg's required setting
+  /// i.e. this arg will be required unless at least one of these other arguments are present.
   pub required_unless_one: Option<Vec<String>>,
+  /// Sets a conflicting argument by name
+  /// i.e. when using this argument, the following argument can't be present and vice versa.
   pub conflicts_with: Option<String>,
+  /// The same as conflictsWith but allows specifying multiple two-way conflicts per argument.
   pub conflicts_with_all: Option<Vec<String>>,
+  /// Tets an argument by name that is required when this one is present
+  /// i.e. when using this argument, the following argument must be present.
   pub requires: Option<String>,
+  /// Sts multiple arguments by names that are required when this one is present
+  /// i.e. when using this argument, the following arguments must be present.
   pub requires_all: Option<Vec<String>>,
+  /// Allows a conditional requirement with the signature [arg, value]
+  /// the requirement will only become valid if `arg`'s value equals `${value}`.
   pub requires_if: Option<Vec<String>>,
+  /// Allows specifying that an argument is required conditionally with the signature [arg, value]
+  /// the requirement will only become valid if the `arg`'s value equals `${value}`.
   pub required_if: Option<Vec<String>>,
+  /// Requires that options use the --option=val syntax
+  /// i.e. an equals between the option and associated value.
   pub require_equals: Option<bool>,
+  /// The positional argument index, starting at 1.
+  ///
+  /// The index refers to position according to other positional argument.
+  /// It does not define position in the argument list as a whole. When utilized with multiple=true,
+  /// only the last positional argument may be defined as multiple (i.e. the one with the highest index).
   pub index: Option<u64>,
 }
 
-#[derive(PartialEq, Deserialize, Debug)]
-#[serde(rename_all = "camelCase")]
-pub struct CliSubcommand {
-  description: Option<String>,
-  long_description: Option<String>,
-  before_help: Option<String>,
-  after_help: Option<String>,
-  args: Option<Vec<CliArg>>,
-  subcommands: Option<HashMap<String, CliSubcommand>>,
-}
-
+/// The CLI root command definition.
 #[derive(PartialEq, Deserialize, Debug)]
 #[serde(tag = "cli", rename_all = "camelCase")]
 pub struct CliConfig {
@@ -117,54 +176,50 @@ pub struct CliConfig {
   before_help: Option<String>,
   after_help: Option<String>,
   args: Option<Vec<CliArg>>,
-  subcommands: Option<HashMap<String, CliSubcommand>>,
+  subcommands: Option<HashMap<String, CliConfig>>,
 }
 
-pub trait Cli {
-  fn args(&self) -> Option<&Vec<CliArg>>;
-  fn subcommands(&self) -> Option<&HashMap<String, CliSubcommand>>;
-  fn description(&self) -> Option<&String>;
-  fn long_description(&self) -> Option<&String>;
-  fn before_help(&self) -> Option<&String>;
-  fn after_help(&self) -> Option<&String>;
-}
-
-macro_rules! impl_cli {
-  ( $($field_name:ident),+ $(,)?) => {
-    $(
-      impl Cli for $field_name {
-
-        fn args(&self) -> Option<&Vec<CliArg>> {
-          self.args.as_ref()
-        }
+impl CliConfig {
+  /// List of args for the command
+  pub fn args(&self) -> Option<&Vec<CliArg>> {
+    self.args.as_ref()
+  }
 
-        fn subcommands(&self) -> Option<&HashMap<String, CliSubcommand>> {
-          self.subcommands.as_ref()
-        }
+  /// List of subcommands of this command
+  pub fn subcommands(&self) -> Option<&HashMap<String, CliConfig>> {
+    self.subcommands.as_ref()
+  }
 
-        fn description(&self) -> Option<&String> {
-          self.description.as_ref()
-        }
+  /// Command description which will be shown on the help information.
+  pub fn description(&self) -> Option<&String> {
+    self.description.as_ref()
+  }
 
-        fn long_description(&self) -> Option<&String> {
-          self.description.as_ref()
-        }
+  /// Command long description which will be shown on the help information.
+  pub fn long_description(&self) -> Option<&String> {
+    self.description.as_ref()
+  }
 
-        fn before_help(&self) -> Option<&String> {
-          self.before_help.as_ref()
-        }
+  /// Adds additional help information to be displayed in addition to auto-generated help.
+  /// This information is displayed before the auto-generated help information.
+  /// This is often used for header information.
+  pub fn before_help(&self) -> Option<&String> {
+    self.before_help.as_ref()
+  }
 
-        fn after_help(&self) -> Option<&String> {
-          self.after_help.as_ref()
-        }
-      }
-    )+
+  /// Adds additional help information to be displayed in addition to auto-generated help.
+  /// This information is displayed after the auto-generated help information.
+  /// This is often used to describe how to use the arguments, or caveats to be noted.
+  pub fn after_help(&self) -> Option<&String> {
+    self.after_help.as_ref()
   }
 }
 
+/// The bundler configuration object.
 #[derive(PartialEq, Deserialize, Debug)]
 #[serde(tag = "bundle", rename_all = "camelCase")]
 pub struct BundleConfig {
+  /// The bundle identifier.
   pub identifier: String,
 }
 
@@ -174,24 +229,29 @@ fn default_bundle() -> BundleConfig {
   }
 }
 
-impl_cli!(CliSubcommand, CliConfig);
-
+/// The Tauri configuration object.
 #[derive(PartialEq, Deserialize, Debug)]
 #[serde(tag = "tauri", rename_all = "camelCase")]
 pub struct TauriConfig {
+  /// The window configuration.
   #[serde(default = "default_window")]
   pub window: WindowConfig,
+  /// The embeddedServer configuration.
   #[serde(default = "default_embedded_server")]
   pub embedded_server: EmbeddedServerConfig,
+  /// The CLI configuration.
   #[serde(default)]
   pub cli: Option<CliConfig>,
+  /// The bundler configuration.
   #[serde(default = "default_bundle")]
   pub bundle: BundleConfig,
 }
 
+/// The Build configuration object.
 #[derive(PartialEq, Deserialize, Debug)]
 #[serde(tag = "build", rename_all = "camelCase")]
 pub struct BuildConfig {
+  /// the devPath config.
   #[serde(default = "default_dev_path")]
   pub dev_path: String,
 }
@@ -200,11 +260,14 @@ fn default_dev_path() -> String {
   "".to_string()
 }
 
+/// The tauri.conf.json mapper.
 #[derive(PartialEq, Deserialize, Debug)]
 #[serde(rename_all = "camelCase")]
 pub struct Config {
+  /// The Tauri configuration.
   #[serde(default = "default_tauri")]
   pub tauri: TauriConfig,
+  /// The build configuration.
   #[serde(default = "default_build")]
   pub build: BuildConfig,
 }
@@ -224,6 +287,7 @@ fn default_build() -> BuildConfig {
   }
 }
 
+/// Gets the static parsed config from `tauri.conf.json`.
 pub fn get() -> crate::Result<&'static Config> {
   if let Some(config) = CONFIG.get() {
     return Ok(config);
@@ -252,7 +316,7 @@ mod test {
     let mut subcommands = std::collections::HashMap::new();
     subcommands.insert(
       "update".to_string(),
-      CliSubcommand {
+      CliConfig {
         description: Some("Updates the app".to_string()),
         long_description: None,
         before_help: None,

+ 10 - 0
tauri-api/src/dir.rs

@@ -3,18 +3,27 @@ use std::fs::{self, metadata};
 use std::path::{Path, PathBuf};
 use tempfile::{self, tempdir};
 
+/// The result of the `read_dir` function.
+///
+/// A DiskEntry is either a file or a directory.
+/// The `children` Vec is always `Some` if the entry is a directory.
 #[derive(Debug, Serialize)]
 pub struct DiskEntry {
+  /// The path to this entry.
   pub path: PathBuf,
+  /// The name of this entry (file name with extension or directory name)
   pub name: Option<String>,
+  /// The children of this entry if it's a directory.
   #[serde(skip_serializing_if = "Option::is_none")]
   pub children: Option<Vec<DiskEntry>>,
 }
 
+/// Checks if the given path is a directory.
 pub fn is_dir<P: AsRef<Path>>(path: P) -> crate::Result<bool> {
   metadata(path).map(|md| md.is_dir()).map_err(|e| e.into())
 }
 
+/// Reads a directory. Can perform recursive operations.
 pub fn read_dir<P: AsRef<Path>>(path: P, recursive: bool) -> crate::Result<Vec<DiskEntry>> {
   let mut files_and_dirs: Vec<DiskEntry> = vec![];
   for entry in fs::read_dir(path)? {
@@ -43,6 +52,7 @@ pub fn read_dir<P: AsRef<Path>>(path: P, recursive: bool) -> crate::Result<Vec<D
   Result::Ok(files_and_dirs)
 }
 
+/// Runs a closure with a temp dir argument.
 pub fn with_temp_dir<F: FnOnce(&tempfile::TempDir) -> ()>(callback: F) -> crate::Result<()> {
   let dir = tempdir()?;
   callback(&dir);

+ 2 - 0
tauri-api/src/file.rs

@@ -8,12 +8,14 @@ use crate::Error;
 pub use extract::*;
 pub use file_move::*;
 
+/// Reads a string file.
 pub fn read_string(file: String) -> crate::Result<String> {
   fs::read_to_string(file)
     .map_err(|err| Error::File(format!("Read_string failed: {}", err)).into())
     .map(|c| c)
 }
 
+/// Reads a binary file.
 pub fn read_binary(file: String) -> crate::Result<Vec<u8>> {
   fs::read(file)
     .map_err(|err| Error::File(format!("Read_binary failed: {}", err)).into())

+ 7 - 0
tauri-api/src/file/extract.rs

@@ -7,18 +7,25 @@ use std::fs;
 use std::io;
 use std::path;
 
+/// The supported archive formats.
 #[derive(Debug, Clone, Copy, PartialEq)]
 pub enum ArchiveFormat {
+  /// Tar archive.
   Tar(Option<Compression>),
+  /// Plain archive.
   Plain(Option<Compression>),
+  /// Zip archive.
   Zip,
 }
 
+/// The supported compression types.
 #[derive(Debug, Clone, Copy, PartialEq)]
 pub enum Compression {
+  /// Gz compression (e.g. `.tar.gz` archives)
   Gz,
 }
 
+/// The extract manager.
 #[derive(Debug)]
 pub struct Extract<'a> {
   source: &'a path::Path,

+ 13 - 2
tauri-api/src/http.rs

@@ -71,7 +71,6 @@ pub struct HttpRequestOptions {
 /// # Examples
 /// ```
 /// # use tauri_api::http::{ HttpRequestBuilder, HttpRequestOptions, make_request, ResponseType };
-/// # fn main() {
 /// let mut builder = HttpRequestBuilder::new("GET", "http://example.com");
 /// let option = builder.response_type(ResponseType::Text)
 ///                     .follow_redirects(false)
@@ -82,7 +81,6 @@ pub struct HttpRequestOptions {
 /// } else {
 ///   println!("Something Happened!");
 /// }
-/// # }
 /// ```
 pub struct HttpRequestBuilder {
   /// The request method (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, CONNECT or TRACE)
@@ -114,6 +112,7 @@ pub struct HttpRequestBuilder {
 }
 
 impl HttpRequestBuilder {
+  /// Initializes a new instance of the HttpRequestBuilder.
   pub fn new(method: impl Into<String>, url: impl Into<String>) -> Self {
     Self {
       method: method.into(),
@@ -132,61 +131,73 @@ impl HttpRequestBuilder {
     }
   }
 
+  /// Sets the request params.
   pub fn params(mut self, params: HashMap<String, String>) -> Self {
     self.params = Some(params);
     self
   }
 
+  /// Sets the request headers.
   pub fn headers(mut self, headers: HashMap<String, String>) -> Self {
     self.headers = Some(headers);
     self
   }
 
+  /// Sets the request body.
   pub fn body(mut self, body: Value) -> Self {
     self.body = Some(body);
     self
   }
 
+  /// Sets whether the request should follow redirects or not.
   pub fn follow_redirects(mut self, follow_redirects: bool) -> Self {
     self.follow_redirects = Some(follow_redirects);
     self
   }
 
+  /// Sets the maximum number of redirections.
   pub fn max_redirections(mut self, max_redirections: u32) -> Self {
     self.max_redirections = Some(max_redirections);
     self
   }
 
+  /// Sets the connection timeout.
   pub fn connect_timeout(mut self, connect_timeout: u64) -> Self {
     self.connect_timeout = Some(connect_timeout);
     self
   }
 
+  /// Sets the read timeout.
   pub fn read_timeout(mut self, read_timeout: u64) -> Self {
     self.read_timeout = Some(read_timeout);
     self
   }
 
+  /// Sets the general request timeout.
   pub fn timeout(mut self, timeout: u64) -> Self {
     self.timeout = Some(timeout);
     self
   }
 
+  /// Sets whether the request allows compressed responses or not.
   pub fn allow_compression(mut self, allow_compression: bool) -> Self {
     self.allow_compression = Some(allow_compression);
     self
   }
 
+  /// Sets the type of the request body.
   pub fn body_type(mut self, body_type: BodyType) -> Self {
     self.body_type = Some(body_type);
     self
   }
 
+  /// Sets the type of the response. Interferes with the way we read the response.
   pub fn response_type(mut self, response_type: ResponseType) -> Self {
     self.response_type = Some(response_type);
     self
   }
 
+  /// Builds the HttpRequestOptions.
   pub fn build(self) -> HttpRequestOptions {
     HttpRequestOptions {
       method: self.method,

+ 22 - 0
tauri-api/src/lib.rs

@@ -1,45 +1,67 @@
+//! The Tauri API interface.
+#![warn(missing_docs, rust_2018_idioms)]
 #![cfg_attr(
   all(not(debug_assertions), target_os = "windows"),
   windows_subsystem = "windows"
 )]
 
+/// The Command API module allows you to manage child processes.
 pub mod command;
+/// The Config module allows you to read the configuration from `tauri.conf.json`.
 pub mod config;
+/// The Dialog API module allows you to show messages and prompt for file paths.
 pub mod dialog;
+/// The Dir module is a helper for file system directory management.
 pub mod dir;
+/// The File API module contains helpers to perform file operations.
 pub mod file;
+/// The HTTP request API.
 pub mod http;
+/// The file system path operations API.
 pub mod path;
+/// The RPC module includes utilities to send messages to the JS layer of the webview.
 pub mod rpc;
+/// TCP ports access API.
 pub mod tcp;
+/// The semver API.
 pub mod version;
 
+/// The CLI args interface.
 #[cfg(feature = "cli")]
 pub mod cli;
 #[cfg(feature = "cli")]
 #[macro_use]
 extern crate clap;
 
+/// The desktop notifications API module.
 #[cfg(feature = "notification")]
 pub mod notification;
 
 pub use tauri_utils::*;
 
+/// Alias for a Result with error type anyhow::Error.
 pub use anyhow::Result;
 use thiserror::Error;
 
+/// The error types.
 #[derive(Error, Debug)]
 pub enum Error {
+  /// The extract archive error.
   #[error("Extract Error:{0}")]
   Extract(String),
+  /// The Command (spawn process) error.
   #[error("Command Error:{0}")]
   Command(String),
+  /// The file operation error.
   #[error("File Error:{0}")]
   File(String),
+  /// The path operation error.
   #[error("Path Error:{0}")]
   Path(String),
+  /// The dialog error.
   #[error("Dialog Error:{0}")]
   Dialog(String),
+  /// The network error.
   #[error("Network Error:{0}")]
   Network(attohttpc::StatusCode),
 }

+ 23 - 3
tauri-api/src/notification.rs

@@ -3,14 +3,30 @@ use crate::config::get as get_config;
 #[cfg(windows)]
 use std::path::MAIN_SEPARATOR;
 
+/// The Notification definition.
+/// Allows you to construct a Notification data and send it.
+///
+/// # Example
+/// ```
+/// use tauri_api::notification::Notification;
+/// // shows a notification with the given title and body
+/// Notification::new()
+///   .title("New message".to_string())
+///   .body("You've got a new message.".to_string())
+///   .show();
+/// ```
 #[allow(dead_code)]
 pub struct Notification {
+  /// The notification body.
   body: Option<String>,
+  /// The notification title.
   title: Option<String>,
+  /// The notification icon.
   icon: Option<String>,
 }
 
 impl Notification {
+  /// Initializes a instance of a Notification.
   pub fn new() -> Self {
     Self {
       body: None,
@@ -19,21 +35,25 @@ impl Notification {
     }
   }
 
-  pub fn body(&mut self, body: String) -> &mut Self {
+  /// Sets the notification body.
+  pub fn body(mut self, body: String) -> Self {
     self.body = Some(body);
     self
   }
 
-  pub fn title(&mut self, title: String) -> &mut Self {
+  /// Sets the notification title.
+  pub fn title(mut self, title: String) -> Self {
     self.title = Some(title);
     self
   }
 
-  pub fn icon(&mut self, icon: String) -> &mut Self {
+  /// Sets the notification icon.
+  pub fn icon(mut self, icon: String) -> Self {
     self.icon = Some(icon);
     self
   }
 
+  /// Shows the notification.
   pub fn show(self) -> crate::Result<()> {
     let mut notification = notify_rust::Notification::new();
     if let Some(body) = self.body {

+ 51 - 16
tauri-api/src/path.rs

@@ -2,29 +2,62 @@ use std::path::PathBuf;
 
 use serde_repr::{Deserialize_repr, Serialize_repr};
 
+/// A Base Directory to use.
+/// The base directory is the optional root of a FS operation.
+/// If informed by the API call, all paths will be relative to the path of the given directory.
+///
+/// For more information, check the [dirs documentation](https://docs.rs/dirs/).
 #[derive(Serialize_repr, Deserialize_repr, Clone, Debug)]
 #[repr(u16)]
 pub enum BaseDirectory {
+  /// The Audio directory.
   Audio = 1,
+  /// The Cache directory.
   Cache,
+  /// The Config directory.
   Config,
+  /// The Data directory.
   Data,
+  /// The LocalData directory.
   LocalData,
+  /// The Desktop directory.
   Desktop,
+  /// The Document directory.
   Document,
+  /// The Download directory.
   Download,
+  /// The Executable directory.
   Executable,
+  /// The Font directory.
   Font,
+  /// The Home directory.
   Home,
+  /// The Picture directory.
   Picture,
+  /// The Public directory.
   Public,
+  /// The Runtime directory.
   Runtime,
+  /// The Template directory.
   Template,
+  /// The Video directory.
   Video,
+  /// The Resource directory.
   Resource,
+  /// The default App config directory.
+  /// Resolves to ${CONFIG_DIR}/${APP_NAME}
   App,
 }
 
+/// Resolves the path with the optional base directory.
+///
+/// # Example
+/// ```
+/// use tauri_api::path::{resolve_path, BaseDirectory};
+/// let path = resolve_path("path/to/something".to_string(), Some(BaseDirectory::Config))
+///   .expect("failed to resolve path");
+/// // path is equal to "/home/${whoami}/.config/path/to/something" on Linux
+/// ```
 pub fn resolve_path(path: String, dir: Option<BaseDirectory>) -> crate::Result<String> {
   if let Some(base_dir) = dir {
     let base_dir_path = match base_dir {
@@ -58,86 +91,87 @@ pub fn resolve_path(path: String, dir: Option<BaseDirectory>) -> crate::Result<S
   }
 }
 
-// Returns the path to the user's audio directory.
+/// Returns the path to the user's audio directory.
 pub fn audio_dir() -> Option<PathBuf> {
   dirs::audio_dir()
 }
 
-// Returns the path to the user's cache directory.
+/// Returns the path to the user's cache directory.
 pub fn cache_dir() -> Option<PathBuf> {
   dirs::cache_dir()
 }
 
-// Returns the path to the user's config directory.
+/// Returns the path to the user's config directory.
 pub fn config_dir() -> Option<PathBuf> {
   dirs::config_dir()
 }
 
-// Returns the path to the user's data directory.
+/// Returns the path to the user's data directory.
 pub fn data_dir() -> Option<PathBuf> {
   dirs::data_dir()
 }
 
-// Returns the path to the user's local data directory.
+/// Returns the path to the user's local data directory.
 pub fn local_data_dir() -> Option<PathBuf> {
   dirs::data_local_dir()
 }
 
-// Returns the path to the user's desktop directory.
+/// Returns the path to the user's desktop directory.
 pub fn desktop_dir() -> Option<PathBuf> {
   dirs::desktop_dir()
 }
 
-// Returns the path to the user's document directory.
+/// Returns the path to the user's document directory.
 pub fn document_dir() -> Option<PathBuf> {
   dirs::document_dir()
 }
 
-// Returns the path to the user's download directory.
+/// Returns the path to the user's download directory.
 pub fn download_dir() -> Option<PathBuf> {
   dirs::download_dir()
 }
 
-// Returns the path to the user's executable directory.
+/// Returns the path to the user's executable directory.
 pub fn executable_dir() -> Option<PathBuf> {
   dirs::executable_dir()
 }
 
-// Returns the path to the user's font directory.
+/// Returns the path to the user's font directory.
 pub fn font_dir() -> Option<PathBuf> {
   dirs::font_dir()
 }
 
-// Returns the path to the user's home directory.
+/// Returns the path to the user's home directory.
 pub fn home_dir() -> Option<PathBuf> {
   dirs::home_dir()
 }
 
-// Returns the path to the user's picture directory.
+/// Returns the path to the user's picture directory.
 pub fn picture_dir() -> Option<PathBuf> {
   dirs::picture_dir()
 }
 
-// Returns the path to the user's public directory.
+/// Returns the path to the user's public directory.
 pub fn public_dir() -> Option<PathBuf> {
   dirs::public_dir()
 }
 
-// Returns the path to the user's runtime directory.
+/// Returns the path to the user's runtime directory.
 pub fn runtime_dir() -> Option<PathBuf> {
   dirs::runtime_dir()
 }
 
-// Returns the path to the user's template directory.
+/// Returns the path to the user's template directory.
 pub fn template_dir() -> Option<PathBuf> {
   dirs::template_dir()
 }
 
-// Returns the path to the user's video dir
+/// Returns the path to the user's video dir
 pub fn video_dir() -> Option<PathBuf> {
   dirs::video_dir()
 }
 
+/// Returns the path to the resource directory of this app.
 pub fn resource_dir() -> Option<PathBuf> {
   crate::platform::resource_dir().ok()
 }
@@ -152,6 +186,7 @@ fn app_name() -> crate::Result<String> {
   Ok(app_name.to_string())
 }
 
+/// Returns the path to the suggested directory for your app config files.
 pub fn app_dir() -> Option<PathBuf> {
   dirs::config_dir().and_then(|mut dir| {
     if let Ok(app_name) = app_name() {

+ 38 - 0
tauri-api/src/rpc.rs

@@ -1,8 +1,46 @@
+/// Formats a function to be evaluated as callback.
+/// If the arg is a string literal, it needs the proper quotes.
+///
+/// # Examples
+/// ```
+/// use tauri_api::rpc::format_callback;
+/// // callback with a string argument
+/// // returns `window["callback-function-name"]("the string response")`
+/// format_callback("callback-function-name".to_string(), r#""the string response""#.to_string());
+/// ```
+///
+/// ```
+/// use tauri_api::rpc::format_callback;
+/// use serde::Serialize;
+/// // callback with JSON argument
+/// #[derive(Serialize)]
+/// struct MyResponse {
+///   value: String
+/// }
+/// // this returns `window["callback-function-name"]({value: "some value"})`
+/// format_callback("callback-function-name".to_string(), serde_json::to_string(&MyResponse {
+///   value: "some value".to_string()
+/// }).expect("failed to serialize type"));
+/// ```
 pub fn format_callback(function_name: String, arg: String) -> String {
   let formatted_string = &format!("window[\"{}\"]({})", function_name, arg);
   formatted_string.to_string()
 }
 
+/// Formats a Result type to its callback version.
+/// Useful for Promises handling.
+///
+/// If the Result is Ok, `format_callback` will be called directly.
+/// If the result is an Err, we assume the error message is a string, and quote it.
+///
+/// # Examples
+/// ```
+/// use tauri_api::rpc::format_callback_result;
+/// // returns `window["success_cb"](5)`
+/// format_callback_result(Ok("5".to_string()), "success_cb".to_string(), "error_cb".to_string());
+/// // returns `window["error_cb"]("error message here")`
+/// format_callback_result(Err("error message here".to_string()), "success_cb".to_string(), "error_cb".to_string());
+/// ```
 pub fn format_callback_result(
   result: Result<String, String>,
   callback: String,

+ 2 - 0
tauri-api/src/tcp.rs

@@ -3,6 +3,7 @@ use std::net::TcpListener;
 use rand;
 use rand::distributions::{Distribution, Uniform};
 
+/// Gets the first available port between 8000 and 9000.
 pub fn get_available_port() -> Option<u16> {
   let mut rng = rand::thread_rng();
   let die = Uniform::from(8000..9000);
@@ -16,6 +17,7 @@ pub fn get_available_port() -> Option<u16> {
   None
 }
 
+/// Checks if the given port is available to use.
 pub fn port_is_available(port: u16) -> bool {
   TcpListener::bind(("127.0.0.1", port)).is_ok()
 }

+ 13 - 0
tauri-utils/src/lib.rs

@@ -1,23 +1,36 @@
+//! Tauri utility helpers
+#![warn(missing_docs, rust_2018_idioms)]
+
+/// Platform helpers
 pub mod platform;
+/// Process helpers
 pub mod process;
 
 pub use anyhow::Result;
 use thiserror::Error;
 
+/// The error types.
 #[derive(Error, Debug)]
 pub enum Error {
+  /// Target triple architecture error
   #[error("Unable to determine target-architecture")]
   Architecture,
+  /// Target triple OS error
   #[error("Unable to determine target-os")]
   OS,
+  /// Target triple environment error
   #[error("Unable to determine target-environment")]
   Environment,
+  /// Target triple unknown target-os error
   #[error("Unknown target_os")]
   Unknown,
+  /// Get parent process error
   #[error("Could not get parent process")]
   ParentProcess,
+  /// Get parent process PID error
   #[error("Could not get parent PID")]
   ParentPID,
+  /// Get child process error
   #[error("Could not get child process")]
   ChildProcess,
 }

+ 8 - 0
tauri-utils/src/platform.rs

@@ -53,6 +53,14 @@ pub fn target_triple() -> Result<String> {
   Ok(format!("{}-{}", arch, os))
 }
 
+/// Computes the resource directory of the current environment.
+///
+/// On Windows, it's the path to the executable.
+///
+/// On Linux, it's `/usr/lib/${exe_name}` when running the bundled app,
+/// and `${exe_dir}/../lib/${exe_name}` when running the app from `src-tauri/target/(debug|release)/`.
+///
+/// On MacOS, it's `${exe_dir}../Resources` (inside .app).
 pub fn resource_dir() -> Result<PathBuf> {
   let exe = std::env::current_exe()?;
   let exe_dir = exe.parent().expect("failed to get exe directory");

+ 1 - 1
tauri-utils/src/process.rs

@@ -4,6 +4,7 @@ use sysinfo;
 
 pub use sysinfo::{Process, ProcessExt, Signal, System, SystemExt};
 
+/// Gets the parent process
 pub fn get_parent_process(system: &mut sysinfo::System) -> Result<&Process, Error> {
   let pid = sysinfo::get_current_pid().unwrap();
   system.refresh_process(pid);
@@ -11,6 +12,5 @@ pub fn get_parent_process(system: &mut sysinfo::System) -> Result<&Process, Erro
   let parent_pid = current_process.parent().ok_or(Error::ParentPID)?;
   let parent_process = system.get_process(parent_pid).ok_or(Error::ParentProcess)?;
 
-  println!("{}", pid);
   Ok(parent_process)
 }

+ 1 - 1
tauri/Cargo.toml

@@ -36,7 +36,7 @@ once_cell = "1.4.0"
 tauri-api = { version = "0.6", path = "../tauri-api" }
 
 [build-dependencies]
-tauri_includedir_codegen = "0.6.0"
+tauri_includedir_codegen = "0.6.1"
 cfg_aliases = "0.1.0"
 
 [dev-dependencies]

+ 19 - 0
tauri/src/app.rs

@@ -5,17 +5,25 @@ mod runner;
 type InvokeHandler = Box<dyn FnMut(&mut WebView<'_, ()>, &str) -> Result<(), String>>;
 type Setup = Box<dyn FnMut(&mut WebView<'_, ()>, String)>;
 
+/// The application runner.
 pub struct App {
+  /// The JS message handler.
   invoke_handler: Option<InvokeHandler>,
+  /// The setup callback, invoked when the webview is ready.
   setup: Option<Setup>,
+  /// The HTML of the splashscreen to render.
   splashscreen_html: Option<String>,
 }
 
 impl App {
+  /// Runs the app until it finishes.
   pub fn run(mut self) {
     runner::run(&mut self).expect("Failed to build webview");
   }
 
+  /// Runs the invoke handler if defined.
+  /// Returns whether the message was consumed or not.
+  /// The message is considered consumed if the handler exists and returns an Ok Result.
   pub(crate) fn run_invoke_handler(
     &mut self,
     webview: &mut WebView<'_, ()>,
@@ -28,25 +36,32 @@ impl App {
     }
   }
 
+  /// Runs the setup callback if defined.
   pub(crate) fn run_setup(&mut self, webview: &mut WebView<'_, ()>, source: String) {
     if let Some(ref mut setup) = self.setup {
       setup(webview, source);
     }
   }
 
+  /// Returns the splashscreen HTML.
   pub fn splashscreen_html(&self) -> Option<&String> {
     self.splashscreen_html.as_ref()
   }
 }
 
+/// The App builder.
 #[derive(Default)]
 pub struct AppBuilder {
+  /// The JS message handler.
   invoke_handler: Option<InvokeHandler>,
+  /// The setup callback, invoked when the webview is ready.
   setup: Option<Setup>,
+  /// The HTML of the splashscreen to render.
   splashscreen_html: Option<String>,
 }
 
 impl AppBuilder {
+  /// Creates a new App bulder.
   pub fn new() -> Self {
     Self {
       invoke_handler: None,
@@ -55,6 +70,7 @@ impl AppBuilder {
     }
   }
 
+  /// Defines the JS message handler callback.
   pub fn invoke_handler<F: FnMut(&mut WebView<'_, ()>, &str) -> Result<(), String> + 'static>(
     mut self,
     invoke_handler: F,
@@ -63,16 +79,19 @@ impl AppBuilder {
     self
   }
 
+  /// Defines the setup callback.
   pub fn setup<F: FnMut(&mut WebView<'_, ()>, String) + 'static>(mut self, setup: F) -> Self {
     self.setup = Some(Box::new(setup));
     self
   }
 
+  /// Defines the splashscreen HTML to render.
   pub fn splashscreen_html(mut self, html: &str) -> Self {
     self.splashscreen_html = Some(html.to_string());
     self
   }
 
+  /// Builds the App.
   pub fn build(self) -> App {
     App {
       invoke_handler: self.invoke_handler,

+ 2 - 1
tauri/src/app/runner.rs

@@ -14,7 +14,7 @@ use super::App;
 use crate::api::tcp::{get_available_port, port_is_available};
 use tauri_api::config::get;
 
-// Main entry point function for running the Webview
+/// Main entry point for running the Webview
 pub(crate) fn run(application: &mut App) -> crate::Result<()> {
   // setup the content using the config struct depending on the compile target
   let main_content = setup_content()?;
@@ -259,6 +259,7 @@ fn build_webview(
   Ok(webview)
 }
 
+// Formats an invoke handler error message to print to console.error
 fn get_api_error_message(arg: &str, handler_error_message: String) -> String {
   format!(
     r#"console.error('failed to match a command for {}, {}')"#,

+ 1 - 0
tauri/src/cli.rs

@@ -1,6 +1,7 @@
 use once_cell::sync::Lazy;
 use tauri_api::cli::Matches;
 
+/// Gets the CLI arg matches.
 pub fn get_matches() -> &'static Option<Matches> {
   static MATCHES: Lazy<Option<Matches>> = Lazy::new(|| tauri_api::cli::get_matches().ok());
 

+ 3 - 0
tauri/src/endpoints.rs

@@ -78,7 +78,10 @@ pub(crate) fn handle<T: 'static>(webview: &mut WebView<'_, T>, arg: &str) -> cra
           callback,
           error,
         } => {
+          #[cfg(write_binary_file)]
           file_system::write_binary_file(webview, file, contents, options, callback, error);
+          #[cfg(not(write_binary_file))]
+          whitelist_error(webview, error, "writeBinaryFile");
         }
         ReadDir {
           path,

+ 50 - 19
tauri/src/endpoints/cmd.rs

@@ -2,59 +2,83 @@ use crate::api::path::BaseDirectory;
 use serde::Deserialize;
 use tauri_api::http::HttpRequestOptions;
 
+/// The options for the directory functions on the file system API.
 #[derive(Deserialize)]
 pub struct DirOperationOptions {
+  /// Whether the API should recursively perform the operation on the directory.
   #[serde(default)]
   pub recursive: bool,
+  /// The base directory of the operation.
+  /// The directory path of the BaseDirectory will be the prefix of the defined directory path.
   pub dir: Option<BaseDirectory>,
 }
 
+/// The options for the file functions on the file system API.
 #[derive(Deserialize)]
 pub struct FileOperationOptions {
+  /// The base directory of the operation.
+  /// The directory path of the BaseDirectory will be the prefix of the defined file path.
   pub dir: Option<BaseDirectory>,
 }
 
+/// The options for the open dialog API.
 #[derive(Deserialize)]
 #[serde(rename_all = "camelCase")]
 pub struct OpenDialogOptions {
+  /// The initial path of the dialog.
   pub filter: Option<String>,
+  /// Whether the dialog allows multiple selection or not.
   #[serde(default)]
   pub multiple: bool,
+  /// Whether the dialog is a directory selection (`true` value) or file selection (`false` value).
   #[serde(default)]
   pub directory: bool,
+  /// The initial path of the dialog.
   pub default_path: Option<String>,
 }
 
+/// The options for the save dialog API.
 #[derive(Deserialize)]
 #[serde(rename_all = "camelCase")]
 pub struct SaveDialogOptions {
+  /// The initial path of the dialog.
   pub filter: Option<String>,
+  /// The initial path of the dialog.
   pub default_path: Option<String>,
 }
 
+/// The options for the notification API.
 #[derive(Deserialize)]
 pub struct NotificationOptions {
+  /// The notification title.
   pub title: Option<String>,
+  /// The notification body.
   pub body: String,
+  /// The notification icon.
   pub icon: Option<String>,
 }
 
+/// The API descriptor.
 #[derive(Deserialize)]
 #[serde(tag = "cmd", rename_all = "camelCase")]
 pub enum Cmd {
+  /// The init command
   Init {},
+  /// The read text file API.
   ReadTextFile {
     path: String,
     options: Option<FileOperationOptions>,
     callback: String,
     error: String,
   },
+  /// The read binary file API.
   ReadBinaryFile {
     path: String,
     options: Option<FileOperationOptions>,
     callback: String,
     error: String,
   },
+  /// The write file API.
   WriteFile {
     file: String,
     contents: String,
@@ -62,6 +86,7 @@ pub enum Cmd {
     callback: String,
     error: String,
   },
+  /// The write binary file API.
   WriteBinaryFile {
     file: String,
     contents: String,
@@ -69,12 +94,14 @@ pub enum Cmd {
     callback: String,
     error: String,
   },
+  /// The read dir API.
   ReadDir {
     path: String,
     options: Option<DirOperationOptions>,
     callback: String,
     error: String,
   },
+  /// The copy file API.
   CopyFile {
     source: String,
     destination: String,
@@ -82,24 +109,28 @@ pub enum Cmd {
     callback: String,
     error: String,
   },
+  /// The create dir API.
   CreateDir {
     path: String,
     options: Option<DirOperationOptions>,
     callback: String,
     error: String,
   },
+  /// The remove dir API.
   RemoveDir {
     path: String,
     options: Option<DirOperationOptions>,
     callback: String,
     error: String,
   },
+  /// The remove file API.
   RemoveFile {
     path: String,
     options: Option<FileOperationOptions>,
     callback: String,
     error: String,
   },
+  /// The rename file API.
   #[serde(rename_all = "camelCase")]
   RenameFile {
     old_path: String,
@@ -108,70 +139,70 @@ pub enum Cmd {
     callback: String,
     error: String,
   },
-  SetTitle {
-    title: String,
-  },
+  /// The set webview title API.
+  SetTitle { title: String },
+  /// The execute script API.
   Execute {
     command: String,
     args: Vec<String>,
     callback: String,
     error: String,
   },
-  Open {
-    uri: String,
-  },
+  /// The open URL in browser API
+  Open { uri: String },
   ValidateSalt {
     salt: String,
     callback: String,
     error: String,
   },
+  /// The event listen API.
   Listen {
     event: String,
     handler: String,
     once: bool,
   },
+  /// The event emit API.
   Emit {
     event: String,
     payload: Option<String>,
   },
+  /// The open dialog API.
   OpenDialog {
     options: OpenDialogOptions,
     callback: String,
     error: String,
   },
+  /// The save dialog API.
   SaveDialog {
     options: SaveDialogOptions,
     callback: String,
     error: String,
   },
+  /// The HTTP request API.
   HttpRequest {
     options: Box<HttpRequestOptions>,
     callback: String,
     error: String,
   },
+  /// The load asset into webview API.
   #[serde(rename_all = "camelCase")]
-  #[cfg(any(feature = "embedded-server", feature = "no-server"))]
+  #[cfg(assets)]
   LoadAsset {
     asset: String,
     asset_type: String,
     callback: String,
     error: String,
   },
-  CliMatches {
-    callback: String,
-    error: String,
-  },
+  /// The get CLI matches API.
+  CliMatches { callback: String, error: String },
+  /// The show notification API.
   Notification {
     options: NotificationOptions,
     callback: String,
     error: String,
   },
-  RequestNotificationPermission {
-    callback: String,
-    error: String,
-  },
-  IsNotificationPermissionGranted {
-    callback: String,
-    error: String,
-  },
+  /// The request notification permission API.
+  RequestNotificationPermission { callback: String, error: String },
+  /// The notification permission check API.
+  IsNotificationPermissionGranted { callback: String, error: String },
 }

+ 3 - 0
tauri/src/endpoints/dialog.rs

@@ -2,6 +2,7 @@ use super::cmd::{OpenDialogOptions, SaveDialogOptions};
 use crate::api::dialog::{pick_folder, save_file, select, select_multiple, Response};
 use web_view::WebView;
 
+/// maps a dialog response to a JS value to eval
 fn map_response(response: Response) -> String {
   match response {
     Response::Okay(path) => format!(r#""{}""#, path).replace("\\", "\\\\"),
@@ -10,6 +11,7 @@ fn map_response(response: Response) -> String {
   }
 }
 
+/// Shows an open dialog.
 #[cfg(open_dialog)]
 pub fn open<T: 'static>(
   webview: &mut WebView<'_, T>,
@@ -34,6 +36,7 @@ pub fn open<T: 'static>(
   );
 }
 
+/// Shows a save dialog.
 #[cfg(save_dialog)]
 pub fn save<T: 'static>(
   webview: &mut WebView<'_, T>,

+ 10 - 0
tauri/src/endpoints/file_system.rs

@@ -10,6 +10,7 @@ use std::io::Write;
 
 use super::cmd::{DirOperationOptions, FileOperationOptions};
 
+/// Reads a directory.
 #[cfg(read_dir)]
 pub fn read_dir<T: 'static>(
   webview: &mut WebView<'_, T>,
@@ -34,6 +35,7 @@ pub fn read_dir<T: 'static>(
   );
 }
 
+/// Copies a file.
 #[cfg(copy_file)]
 pub fn copy_file<T: 'static>(
   webview: &mut WebView<'_, T>,
@@ -62,6 +64,7 @@ pub fn copy_file<T: 'static>(
   );
 }
 
+/// Creates a directory.
 #[cfg(create_dir)]
 pub fn create_dir<T: 'static>(
   webview: &mut WebView<'_, T>,
@@ -92,6 +95,7 @@ pub fn create_dir<T: 'static>(
   );
 }
 
+/// Removes a directory.
 #[cfg(remove_dir)]
 pub fn remove_dir<T: 'static>(
   webview: &mut WebView<'_, T>,
@@ -122,6 +126,7 @@ pub fn remove_dir<T: 'static>(
   );
 }
 
+/// Removes a file
 #[cfg(remove_file)]
 pub fn remove_file<T: 'static>(
   webview: &mut WebView<'_, T>,
@@ -143,6 +148,7 @@ pub fn remove_file<T: 'static>(
   );
 }
 
+/// Renames a file.
 #[cfg(rename_file)]
 pub fn rename_file<T: 'static>(
   webview: &mut WebView<'_, T>,
@@ -171,6 +177,7 @@ pub fn rename_file<T: 'static>(
   );
 }
 
+/// Writes a text file.
 #[cfg(write_file)]
 pub fn write_file<T: 'static>(
   webview: &mut WebView<'_, T>,
@@ -196,6 +203,7 @@ pub fn write_file<T: 'static>(
   );
 }
 
+/// Writes a binary file.
 #[cfg(write_binary_file)]
 pub fn write_binary_file<T: 'static>(
   webview: &mut WebView<'_, T>,
@@ -225,6 +233,7 @@ pub fn write_binary_file<T: 'static>(
   );
 }
 
+/// Reads a text file.
 #[cfg(read_text_file)]
 pub fn read_text_file<T: 'static>(
   webview: &mut WebView<'_, T>,
@@ -244,6 +253,7 @@ pub fn read_text_file<T: 'static>(
   );
 }
 
+/// Reads a binary file.
 #[cfg(read_binary_file)]
 pub fn read_binary_file<T: 'static>(
   webview: &mut WebView<'_, T>,

+ 1 - 1
tauri/src/endpoints/http.rs

@@ -1,7 +1,7 @@
 use tauri_api::http::{make_request as request, HttpRequestOptions, ResponseType};
 use web_view::WebView;
 
-/// Makes a HTTP request and resolves the response to the webview
+/// Makes an HTTP request and resolves the response to the webview
 pub fn make_request<T: 'static>(
   webview: &mut WebView<'_, T>,
   options: HttpRequestOptions,

+ 3 - 3
tauri/src/endpoints/notification.rs

@@ -11,12 +11,12 @@ pub fn send<T: 'static>(
     webview,
     move || {
       let mut notification = tauri_api::notification::Notification::new();
-      notification.body(options.body);
+      notification = notification.body(options.body);
       if let Some(title) = options.title {
-        notification.title(title);
+        notification = notification.title(title);
       }
       if let Some(icon) = options.icon {
-        notification.icon(icon);
+        notification = notification.icon(icon);
       }
       notification
         .show()

+ 1 - 0
tauri/src/endpoints/salt.rs

@@ -1,5 +1,6 @@
 use web_view::WebView;
 
+/// Validates a salt.
 pub fn validate<T: 'static>(
   webview: &mut WebView<'_, T>,
   salt: String,

+ 9 - 0
tauri/src/event.rs

@@ -6,7 +6,9 @@ use lazy_static::lazy_static;
 use once_cell::sync::Lazy;
 use web_view::Handle;
 
+/// An event handler.
 struct EventHandler {
+  /// The on event callback.
   on_event: Box<dyn FnMut(Option<String>) + Send>,
 }
 
@@ -18,23 +20,28 @@ lazy_static! {
   static ref EVENT_QUEUE_OBJECT_NAME: String = uuid::Uuid::new_v4().to_string();
 }
 
+/// Gets the listeners map.
 fn listeners() -> &'static Listeners {
   static LISTENERS: Lazy<Listeners> = Lazy::new(|| Arc::new(Mutex::new(HashMap::new())));
   &LISTENERS
 }
 
+/// the emit JS function name
 pub fn emit_function_name() -> String {
   EMIT_FUNCTION_NAME.to_string()
 }
 
+/// the event listeners JS object name
 pub fn event_listeners_object_name() -> String {
   EVENT_LISTENERS_OBJECT_NAME.to_string()
 }
 
+/// the event queue JS object name
 pub fn event_queue_object_name() -> String {
   EVENT_QUEUE_OBJECT_NAME.to_string()
 }
 
+/// Adds an event listener for JS events.
 pub fn listen<F: FnMut(Option<String>) + Send + 'static>(id: String, handler: F) {
   let mut l = listeners()
     .lock()
@@ -47,6 +54,7 @@ pub fn listen<F: FnMut(Option<String>) + Send + 'static>(id: String, handler: F)
   );
 }
 
+/// Emits an event to JS.
 pub fn emit<T: 'static>(webview_handle: &Handle<T>, event: String, payload: Option<String>) {
   let salt = crate::salt::generate();
 
@@ -69,6 +77,7 @@ pub fn emit<T: 'static>(webview_handle: &Handle<T>, event: String, payload: Opti
     .expect("Failed to dispatch JS from emit");
 }
 
+/// Triggers the given event with its payload.
 pub fn on_event(event: String, data: Option<String>) {
   let mut l = listeners()
     .lock()

+ 23 - 1
tauri/src/lib.rs

@@ -1,25 +1,40 @@
+//! Tauri is a framework for building tiny, blazing fast binaries for all major desktop platforms.
+//! Developers can integrate any front-end framework that compiles to HTML, JS and CSS for building their user interface.
+//! The backend of the application is a rust-sourced binary with an API that the front-end can interact with.
+//!
+//! The user interface in Tauri apps currently leverages Cocoa/WebKit on macOS, gtk-webkit2 on Linux and MSHTML (IE10/11) or Webkit via Edge on Windows.
+//! Tauri uses (and contributes to) the MIT licensed project that you can find at [webview](https://github.com/webview/webview).
+#![warn(missing_docs, rust_2018_idioms)]
 #![cfg_attr(
   all(not(debug_assertions), target_os = "windows"),
   windows_subsystem = "windows"
 )]
 
+/// The asset management module.
 #[cfg(assets)]
 pub mod assets;
+/// The event system module.
 pub mod event;
+/// The embedded server helpers.
 #[cfg(embedded_server)]
 pub mod server;
+/// The Tauri-specific settings for your app e.g. notification permission status.
 pub mod settings;
 
+/// The CLI args interface.
 #[cfg(cli)]
 pub mod cli;
 
+/// The webview application entry.
 mod app;
+/// The Tauri API endpoints.
 mod endpoints;
-#[allow(dead_code)]
+/// The salt helpers.
 mod salt;
 
 use std::process::Stdio;
 
+/// Alias for a Result with error type anyhow::Error.
 pub use anyhow::Result;
 use threadpool::ThreadPool;
 
@@ -30,6 +45,7 @@ pub use app::*;
 pub use tauri_api as api;
 thread_local!(static POOL: ThreadPool = ThreadPool::new(4));
 
+/// Executes the operation in the thread pool.
 pub fn spawn<F: FnOnce() -> () + Send + 'static>(task: F) {
   POOL.with(|thread| {
     thread.execute(move || {
@@ -38,6 +54,8 @@ pub fn spawn<F: FnOnce() -> () + Send + 'static>(task: F) {
   });
 }
 
+/// Synchronously executes the given task
+/// and evaluates its Result to the JS promise described by the `callback` and `error` function names.
 pub fn execute_promise_sync<T: 'static, F: FnOnce() -> crate::Result<String> + Send + 'static>(
   webview: &mut WebView<'_, T>,
   task: F,
@@ -52,6 +70,8 @@ pub fn execute_promise_sync<T: 'static, F: FnOnce() -> crate::Result<String> + S
     .expect("Failed to dispatch promise callback");
 }
 
+/// Asynchronously executes the given task
+/// and evaluates its Result to the JS promise described by the `callback` and `error` function names.
 pub fn execute_promise<T: 'static, F: FnOnce() -> crate::Result<String> + Send + 'static>(
   webview: &mut WebView<'_, T>,
   task: F,
@@ -70,6 +90,7 @@ pub fn execute_promise<T: 'static, F: FnOnce() -> crate::Result<String> + Send +
   });
 }
 
+/// Calls the given command and evaluates its output to the JS promise described by the `callback` and `error` function names.
 pub fn call<T: 'static>(
   webview: &mut WebView<'_, T>,
   command: String,
@@ -89,6 +110,7 @@ pub fn call<T: 'static>(
   );
 }
 
+/// Closes the splashscreen.
 pub fn close_splashscreen<T: 'static>(webview_handle: &Handle<T>) -> crate::Result<()> {
   webview_handle.dispatch(|webview| {
     // send a signal to the runner so it knows that it should redirect to the main app content

+ 5 - 0
tauri/src/salt.rs

@@ -3,6 +3,7 @@ use std::sync::Mutex;
 use lazy_static::lazy_static;
 use uuid::Uuid;
 
+/// A salt definition.
 struct Salt {
   value: String,
   one_time: bool,
@@ -12,6 +13,7 @@ lazy_static! {
   static ref SALTS: Mutex<Vec<Salt>> = Mutex::new(vec![]);
 }
 
+/// Generates a one time Salt and returns its string representation.
 pub fn generate() -> String {
   let salt = Uuid::new_v4();
   SALTS
@@ -24,6 +26,8 @@ pub fn generate() -> String {
   salt.to_string()
 }
 
+/// Generates a static Salt and returns its string representation.
+#[allow(dead_code)]
 pub fn generate_static() -> String {
   let salt = Uuid::new_v4();
   SALTS
@@ -36,6 +40,7 @@ pub fn generate_static() -> String {
   salt.to_string()
 }
 
+/// Checks if the given Salt representation is valid.
 pub fn is_valid(salt: String) -> bool {
   let mut salts = SALTS.lock().expect("Failed to lock Salt mutex: is_valid()");
   match salts.iter().position(|s| s.value == salt) {

+ 1 - 0
tauri/src/server.rs

@@ -1,5 +1,6 @@
 use tiny_http::{Header, Response};
 
+/// Returns the HTTP response of the given asset path.
 pub fn asset_response(path: &str) -> Response<std::io::Cursor<Vec<u8>>> {
   let asset_path = &format!(
     "{}{}",

+ 5 - 0
tauri/src/settings.rs

@@ -6,16 +6,20 @@ use std::path::Path;
 use tauri_api::file::read_string;
 use tauri_api::path::{resolve_path, BaseDirectory};
 
+/// Tauri Settings.
 #[derive(Default, Deserialize, Serialize)]
 pub struct Settings {
+  /// Whether the user allows notifications or not.
   #[cfg(notification)]
   pub allow_notification: Option<bool>,
 }
 
+/// Gets the path to the settings file
 fn get_settings_path() -> tauri_api::Result<String> {
   resolve_path(".tauri-settings.json".to_string(), Some(BaseDirectory::App))
 }
 
+/// Write the settings to the file system.
 pub(crate) fn write_settings(settings: Settings) -> crate::Result<()> {
   let settings_path = get_settings_path()?;
   let settings_folder = Path::new(&settings_path).parent().unwrap();
@@ -30,6 +34,7 @@ pub(crate) fn write_settings(settings: Settings) -> crate::Result<()> {
     })
 }
 
+/// Reads the settings from the file system.
 pub fn read_settings() -> crate::Result<Settings> {
   let settings_path = get_settings_path()?;
   if Path::new(settings_path.as_str()).exists() {