/* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include #include #include "common/libs/utils/collect.h" #include "common/libs/utils/contains.h" #include "common/libs/utils/result.h" #include "host/commands/cvd/selector/constant_reference.h" #include "host/commands/cvd/selector/instance_database_types.h" namespace cuttlefish { namespace selector { Result GetCuttlefishConfigPath(const std::string& home); std::string GenInternalGroupName(); std::string GenDefaultGroupName(); std::string LocalDeviceNameRule(const std::string& group_name, const std::string& instance_name); // [A-Za-z0-9_]+, e.g. 0, tv, my_phone07, etc // Or, it can include "-" in the middle // ([A-Za-z0-9_]+[-])*[A-Za-z0-9_] bool IsValidInstanceName(const std::string& token); // [A-Za-z_][A-Za-z0-9_]*, e.g. cool_group, cv0_d, cf, etc // but can't start with [0-9] bool IsValidGroupName(const std::string& token); // - bool IsValidDeviceName(const std::string& token); struct DeviceName { std::string group_name; std::string per_instance_name; }; Result BreakDeviceName(const std::string& device_name); /** * Runs simple tests to see if it could potentially be a host artifacts dir * */ bool PotentiallyHostArtifactsPath(const std::string& host_binaries_dir); /** * simply returns: * * "Only up to n must match" or * "Only up to n must match by field " + FieldName * */ std::string GenerateTooManyInstancesErrorMsg(const int n, const std::string& field_name); /** * return all the elements in container that satisfies predicate. * * Container has Wrappers, where each Wrapper is typically, * std::unique/shared_ptr of T, or some wrapper of T, etc. Set is a set of T. * * This method returns the Set of T, as long as its corresponding Wrapper in * Container meets the predicate. */ template Set Collect(const Container& container, std::function predicate, std::function convert) { Set output; for (const auto& t : container) { if (!predicate(t)) { continue; } output.insert(convert(t)); } return output; } /* * Returns a Set of ConstRef, which essentially satisfies "predicate" * * Container has a list/set of std::unique_ptr. We collect all the * const references of each object owned by Container, which meets the * condition defined by predicate. * */ template Set> CollectToSet( Container&& container, std::function&)> predicate) { auto convert = [](const std::unique_ptr& uniq_ptr) { return Cref(*uniq_ptr); }; return Collect, std::unique_ptr, Set>>( std::forward(container), std::move(predicate), std::move(convert)); } /** * Given: * Containers have a list of n `Container`s. Each Container may have * m Element. Each is stored as a unique_ptr. * * Goal: * To collect Elements from each Container with Container's APIs. The * collected Elements meet the condition implicitly defined in collector. * * E.g. InstanceDatabase has InstanceGroups, each has Instances. We want * all the Instances its build-target was TV. Then, collector will look * like this: * [&build_target](const std::unique_ptr& group) { * return group->FindByBuildTarget(build_target); * } * * We take the union of all the returned subsets from each collector call. */ template Result>> CollectAllElements( std::function< Result>>(const std::unique_ptr&)> collector, const Containers& outermost_container) { Set> output; for (const auto& container_ptr : outermost_container) { auto subset = CF_EXPECT(collector(container_ptr)); output.insert(subset.cbegin(), subset.cend()); } return {output}; } template Result::type> AtMostOne( S&& s, const std::string& err_msg) { CF_EXPECT(AtMostN(std::forward(s), 1), err_msg); return {std::forward(s)}; } template RetSet Intersection(const RetSet& u, AnyContainer&& v) { RetSet result; if (u.empty() || v.empty()) { return result; } for (auto const& e : v) { if (Contains(u, e)) { result.insert(e); } } return result; } template RetSet Intersection(const RetSet& u, AnyContainer&& v, Containers&&... s) { RetSet first = Intersection(u, std::forward(v)); if (first.empty()) { return first; } return Intersection(first, std::forward(s)...); } } // namespace selector } // namespace cuttlefish