1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95

build / rust / chromium_prelude / chromium_prelude.rs [blame]

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/// The `chromium::import!{}` macro for importing crates from GN paths.
///
/// This macro is used to access first-party crates in the Chromium project
/// (or other projects using Chromium's //build system) through the GN path
/// to the crate. All GN paths must be absolute paths.
///
/// Third-party crates are accessed as usual by their name, which is available
/// whenever the Rust target depends on the third-party crate. The `import!`
/// macro does nothing, and will cause a compilation error if an attempt is
/// made to import a third-party crate with it.
///
/// # Motivation
///
/// Since first-party crates do not all have globally unique GN names, using
/// their GN target name as their crate name leads to ambiguity when multiple
/// crates with the same name are dependencies of the same crate. As such, we
/// produce mangled crate names that are unique, and depend on their full GN
/// path, but these names are not easy to spell.
///
/// # Usage
///
/// The `chromium` crate is automatically present in all first-party Rust
/// targets, which makes the `chromium::import!{}` macro available. The macro
/// should be given a list of GN paths (directory and target name) as quoted
/// strings to be imported into the current module, delineated with semicolons.
///
/// When no target name is specified (e.g. `:name`) at the end of the GN path,
/// the target will be the same as the last directory name. This is the same
/// behaviour as within the GN `deps` list.
///
/// The imported crates can be renamed by using the `as` keyword and reexported
/// using the `pub` keyword. These function in the same way as they do when
/// naming or reexporting with `use`, but the `import!` macro replaces the `use`
/// keyword for these purposes with first-party crates.
///
/// # Examples
///
/// ## Basic usage
/// Basic usage, importing a few targets. The name given to the imported crates
/// is their GN target name by default. In this example, there would be two
/// crates available in the Rust module below: `example` which is the
/// `example` GN target in `rust/example/BUILD.gn` and `other` which is the
/// `other` GN target in `rust/example/BUILD.gn`.
/// ```
/// chromium::import! {
///   "//rust/example";
///   "//rust/example:other";
/// }
///
/// use example::Goat;
///
/// example::foo(Goat::new());
/// other::foo(Goat::with_age(3));
/// ```
///
/// ## Renaming an import
/// Since multiple GN targets may have the same local name, they can be given
/// a different name when imported by using `as`:
/// ```
/// chromium::import! {
///   "//rust/example" as renamed;
///   "//rust/example:other" as very_renamed;
/// }
///
/// use renamed::Goat;
///
/// renamed::foo(Goat::new());
/// very_renamed::foo(Goat::with_age(3));
/// ```
///
/// ## Re-exporting
/// When importing and re-exporting a dependency, the usual syntax would be
/// `pub use my_dependency;`. For first-party crates, this must be done through
/// the `import!` macro by prepending the `pub` keyword where the crate is
/// imported. The exported name can be specified with `as`:
/// ```
/// mod module {
///
/// chromium::import! {
///   pub "//rust/example";
///   pub "//rust/example:other" as exported_other;
/// }
///
/// }
///
/// use module::example::Goat;
///
/// module::example::foo(Goat::new())
/// module::exported_other::foo(Goat::with_age(3));
/// ```
pub use import_attribute::import;