Skip to main content

miden_project/
target.rs

1use alloc::string::{String, ToString};
2
3use miden_assembly_syntax::Path;
4
5use crate::*;
6
7/// Represents build target configuration
8#[derive(Debug, Clone, PartialEq, Eq)]
9pub struct Target {
10    pub ty: TargetType,
11    /// The effective name of this target
12    ///
13    /// If unspecified in the project file, the name is the same as `namespace`
14    ///
15    /// The name must be unique within a project
16    pub name: Span<Arc<str>>,
17    /// The namespace root for this target
18    pub namespace: Span<Arc<Path>>,
19    /// The path from the project manifest to the root source file for this target
20    ///
21    /// The path can be to a source file written in any language, e.g. for MASM it might refer to
22    /// `mod.masm`, while for Rust it might refer to `src/lib.rs` - as long as an appropriate
23    /// source provider is registered with the assembler.
24    pub path: Span<Uri>,
25}
26
27impl Target {
28    /// Construct a new executable target named `name` and given source `uri`
29    pub fn executable(name: impl Into<Arc<str>>, uri: Uri) -> Self {
30        Self::new(TargetType::Executable, name.into(), Path::exec_path(), uri)
31    }
32
33    /// Construct a new library target named `name` with the given `namespace` and source `uri`
34    pub fn library(namespace: impl Into<Arc<Path>>, uri: Uri) -> Self {
35        let namespace = namespace.into();
36        let name: Arc<str> = namespace.as_str().into();
37        Self::new(TargetType::Library, name, namespace, uri)
38    }
39
40    /// Construct a new target of type `ty`, with the given `name`, `namespace` and source `uri`
41    pub fn new(
42        ty: TargetType,
43        name: impl Into<Arc<str>>,
44        namespace: impl Into<Arc<Path>>,
45        uri: Uri,
46    ) -> Self {
47        Self {
48            ty,
49            name: Span::unknown(name.into()),
50            namespace: Span::unknown(namespace.into()),
51            path: Span::unknown(uri),
52        }
53    }
54
55    /// Returns true if this target is an executable target
56    pub const fn is_executable(&self) -> bool {
57        matches!(self.ty, TargetType::Executable)
58    }
59
60    /// Returns true if this target is a non-executable target
61    pub const fn is_library(&self) -> bool {
62        !self.is_executable()
63    }
64
65    /// Returns true if this target is a kernel target
66    pub const fn is_kernel(&self) -> bool {
67        matches!(self.ty, TargetType::Kernel)
68    }
69
70    /// Append the selected target fields that affect package artifact reuse to `out`.
71    pub fn append_build_provenance_projection(&self, out: &mut String) {
72        let Self { ty, name, namespace, path } = self;
73
74        out.push_str("target:kind:");
75        out.push_str(ty.to_string().as_str());
76        out.push('\n');
77        out.push_str("target:name:");
78        out.push_str(name.inner().as_ref());
79        out.push('\n');
80        out.push_str("target:namespace:");
81        out.push_str(namespace.inner().as_str());
82        out.push('\n');
83        out.push_str("target:path:");
84        out.push_str(path.inner().as_str());
85        out.push('\n');
86    }
87}