|
2 | 2 | //! |
3 | 3 | //! There are no guarantees that this schema will remain stable across Pavex versions: |
4 | 4 | //! it is considered (for the time being) an internal implementation detail of Pavex's reflection system. |
5 | | -use pavex_reflection::AnnotationCoordinates; |
6 | | -pub use pavex_reflection::{CreatedAt, CreatedBy, Location}; |
7 | 5 | use std::collections::{BTreeMap, BTreeSet}; |
8 | 6 | use std::fmt; |
9 | 7 | use std::fmt::Formatter; |
@@ -363,3 +361,121 @@ pub enum Sources { |
363 | 361 | /// Each module can be either from the current crate or from one of its direct dependencies. |
364 | 362 | Some(Vec<String>), |
365 | 363 | } |
| 364 | + |
| 365 | +#[derive(Clone, Debug, Eq, PartialEq, Hash, serde::Serialize, serde::Deserialize)] |
| 366 | +/// A set of coordinates to identify a precise spot in a source file. |
| 367 | +/// |
| 368 | +/// # Implementation Notes |
| 369 | +/// |
| 370 | +/// `Location` is an owned version of [`std::panic::Location`]. |
| 371 | +/// You can build a `Location` instance starting from a [`std::panic::Location`]: |
| 372 | +/// |
| 373 | +/// ```rust |
| 374 | +/// use pavex_reflection::Location; |
| 375 | +/// |
| 376 | +/// let location: Location = std::panic::Location::caller().into(); |
| 377 | +/// ``` |
| 378 | +pub struct Location { |
| 379 | + /// The line number. |
| 380 | + /// |
| 381 | + /// Lines are 1-indexed (i.e. the first line is numbered as 1, not 0). |
| 382 | + pub line: u32, |
| 383 | + /// The column number. |
| 384 | + /// |
| 385 | + /// Columns are 1-indexed (i.e. the first column is numbered as 1, not 0). |
| 386 | + pub column: u32, |
| 387 | + /// The name of the source file. |
| 388 | + /// |
| 389 | + /// Check out [`std::panic::Location::file`] for more details. |
| 390 | + pub file: String, |
| 391 | +} |
| 392 | + |
| 393 | +impl<'a> From<&'a std::panic::Location<'a>> for Location { |
| 394 | + fn from(l: &'a std::panic::Location<'a>) -> Self { |
| 395 | + Self { |
| 396 | + line: l.line(), |
| 397 | + column: l.column(), |
| 398 | + file: l.file().into(), |
| 399 | + } |
| 400 | + } |
| 401 | +} |
| 402 | + |
| 403 | +impl Location { |
| 404 | + #[track_caller] |
| 405 | + pub fn caller() -> Self { |
| 406 | + std::panic::Location::caller().into() |
| 407 | + } |
| 408 | +} |
| 409 | + |
| 410 | +#[derive(Debug, Hash, Eq, PartialEq, Clone, serde::Serialize, serde::Deserialize)] |
| 411 | +/// The method used to create (and set the properties) for this component. |
| 412 | +pub enum CreatedBy { |
| 413 | + /// The component was created via a macro annotation (e.g. `#[pavex::wrap]`) |
| 414 | + /// on top of the target item (e.g. a function or a method). |
| 415 | + Attribute { name: String }, |
| 416 | + /// The component was provided by the framework. |
| 417 | + /// |
| 418 | + /// For example, the default fallback handler if the user didn't specify one. |
| 419 | + Framework, |
| 420 | +} |
| 421 | + |
| 422 | +impl CreatedBy { |
| 423 | + /// Convert the name of the macro used to perform the registration into an instance of [`CreatedBy`]. |
| 424 | + pub fn macro_name(value: &str) -> Self { |
| 425 | + match value { |
| 426 | + "pre_process" | "post_process" | "wrap" | "request_scoped" | "transient" |
| 427 | + | "singleton" | "config" | "error_handler" | "error_observer" | "fallback" |
| 428 | + | "route" => CreatedBy::Attribute { name: value.into() }, |
| 429 | + _ => panic!( |
| 430 | + "Pavex doesn't recognize `{value}` as one of its macros to register components" |
| 431 | + ), |
| 432 | + } |
| 433 | + } |
| 434 | +} |
| 435 | + |
| 436 | +#[derive(Debug, Hash, Eq, PartialEq, Clone, serde::Serialize, serde::Deserialize)] |
| 437 | +pub struct AnnotationCoordinates { |
| 438 | + /// An opaque string that uniquely identifies this component within the package |
| 439 | + /// where it was defined. |
| 440 | + pub id: String, |
| 441 | + /// Metadata required to pinpoint where the annotated component lives. |
| 442 | + pub created_at: CreatedAt, |
| 443 | + /// The name of the macro used to annotate the component. |
| 444 | + pub macro_name: String, |
| 445 | +} |
| 446 | + |
| 447 | +#[derive(Clone, Debug, Eq, PartialEq, Hash, serde::Serialize, serde::Deserialize)] |
| 448 | +/// Information on the crate/module where the component was created. |
| 449 | +/// |
| 450 | +/// This location matches, for example, where the `from!` or the `f!` macro were invoked. |
| 451 | +/// For annotated items (e.g. via `#[pavex::config]`), this refers to the location of the annotation. |
| 452 | +/// |
| 453 | +/// It may be different from the location where the component was registered |
| 454 | +/// with the blueprint—i.e. where a `Blueprint` method was invoked. |
| 455 | +pub struct CreatedAt { |
| 456 | + /// The name of the crate that created the component, as it appears in the `package.name` field |
| 457 | + /// of its `Cargo.toml`. |
| 458 | + /// Obtained via [`CARGO_PKG_NAME`](https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates). |
| 459 | + /// |
| 460 | + /// In particular, the name has *not* been normalised—e.g. hyphens are not replaced with underscores. |
| 461 | + /// |
| 462 | + /// This information is needed to resolve the import path unambiguously. |
| 463 | + /// |
| 464 | + /// E.g. `my_crate::module_1::type_2`—which crate is `my_crate`? |
| 465 | + /// This is not obvious due to the possibility of [renaming dependencies in `Cargo.toml`](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html?highlight=rename,depende#renaming-dependencies-in-cargotoml): |
| 466 | + /// |
| 467 | + /// ```toml |
| 468 | + /// [package] |
| 469 | + /// name = "mypackage" |
| 470 | + /// version = "0.0.1" |
| 471 | + /// |
| 472 | + /// [dependencies] |
| 473 | + /// my_crate = { version = "0.1", registry = "custom", package = "their_crate" } |
| 474 | + /// ``` |
| 475 | + pub package_name: String, |
| 476 | + /// The version of the crate that created the component, as it appears in the `package.version` field |
| 477 | + /// of its `Cargo.toml`. |
| 478 | + /// |
| 479 | + /// Obtained via [`CARGO_PKG_VERSION`](https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates). |
| 480 | + pub package_version: String, |
| 481 | +} |
0 commit comments