# Copyright 2018 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//build/rust/rustc_test.gni")

# Defines a Rust library
#
# Parameters
#
#   name
#     Name of the crate as defined in its manifest file. If not specified, it is
#     assumed to be the same as the target name. All dashes will be replaced
#     with underscores in the library name: <name_underscored>
#
#   version
#     Semver version of the crate as seen on crates.io.
#
#   edition (optional)
#     Edition of the Rust language to be used.
#     Options are "2015" and "2018". Defaults to "2018".
#
#   configs (optional)
#     A list of config labels applying to this target.
#
#   deps (optional)
#     List of rust_library GN targets on which this crate depends.
#     Third party crates can be included through paths like
#     "//third_party/rust_crates:<cratename>",
#
#   test_deps (optional)
#     List of rust_library GN targets on which this crate's tests depend.
#
#   non_rust_deps (optional)
#     List of non-rust_library GN targets on which this crate depends.
#
#   with_unit_tests (optional)
#     Builds unit tests associated with the binary. This will create a
#     `<name>_lib_test` test file in the output directory. Equivalent
#     to adding a `rustc_test` target with that name and the same source_root.
#
#   test_environments (optional)
#     What environments unit tests, if provided, should target. Only used here
#     for linux and mac tests, with a default value of a general linux/mac
#     environment (as a function of $current_os).
#     See environments parameter on //build/testing/test_spec.gni for more
#     details.
#
#   source_root (optional)
#     Location of the crate root (e.g. `src/main.rs` or `src/lib.rs`).
#     This defaults to `./src/main.rs` for binaries and `./src/lib.rs` for libraries,
#     and should only be changed when absolutely necessary
#     (such as in the case of generated code).
#
#   features (optional)
#     A list of conditional compilation flags to enable. This can be used to set features for crates
#     built in-tree which are also published to crates.io. This would be passed to rustc as
#     '--cfg feature=XXX'
#
# Example of usage:
#
#   rustc_library("foo-bar") {
#     deps = [
#       "//garnet/public/rust/bar",
#       "//third_party/rust_crates:clap",
#       "//third_party/rust_crates:serde",
#       "//third_party/rust_crates:slab",
#     ]
#     with_unit_tests = true
#   }
#
# Example of using the outputs of the above:
#
#   test_package("foo-bar-tests") {
#     deps = [
#       ":foo-bar_test",
#     ]
#
#    tests = [
#      {
#        name = "foo_bar_lib_test"
#      }
#    ]
#
template("rustc_library") {
  # TODO(bwb) remove all versions from the callers
  # this is a hold-over. It's just noise right now.
  not_needed(invoker, [ "version" ])

  # if "with_unit_tests" is set to true, generate an additional rust test target
  # TODO(bwb) deprecate this. All tests should be declared independently
  if (defined(invoker.with_unit_tests) && invoker.with_unit_tests == true) {
    rustc_test("${target_name}_test") {
      name = invoker.target_name + "_lib_test"
      if (defined(invoker.name)) {
        name = invoker.name + "_lib_test"
      }
      forward_variables_from(invoker,
                             "*",
                             [
                               "name",
                               "configs",
                             ])
    }
  }

  if (defined(invoker.name)) {
    output_name = invoker.name
  } else {
    output_name = target_name
  }

  if (defined(invoker.source_root)) {
    source_root = invoker.source_root
  } else {
    source_root = "src/lib.rs"
  }

  if (defined(invoker.name)) {
    package_name = invoker.name
  } else {
    package_name = target_name
  }
  crate_name = string_replace(package_name, "-", "_")

  features = []
  if (defined(invoker.features)) {
    foreach(i, invoker.features) {
      features += [ "--cfg=feature=\"${i}\"" ]
    }
  }

  rust_library(target_name) {
    crate_root = source_root
    crate_name = crate_name
    output_name = crate_name

    configs = []
    configs = invoker.configs

    deps = []
    if (defined(invoker.deps)) {
      deps += invoker.deps
    }

    if (defined(invoker.non_rust_deps)) {
      deps += invoker.non_rust_deps
    }

    rustflags = features

    if (defined(invoker.edition) && invoker.edition == "2015") {
      configs -= [ "//build/config:rust_edition_2018" ]
      configs += [ "//build/config:rust_edition_2015" ]
    }

    forward_variables_from(invoker,
                           [
                             "testonly",
                             "visibility",
                           ])
  }
}
