//! Tupã core library — types, traits, and pipeline macro re-export.

/// Re-export the procedural macro so users can write `use tupa_core::pipeline;`
pub use tupa_core_macros::pipeline;

/// Re-export serde_json for generated code.
pub use serde_json;

// ============================================================================
// Core types
// ============================================================================

use std::marker::PhantomData;

/// A value with a compile-time proven constraint marker `C`.
///
/// The constraint type `C` is a zero-sized marker. Example:
/// ```rust,ignore
/// type X = Safe<f64, !nan>;
/// ```
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct Safe<T, C>(pub T, PhantomData<C>);

impl<T, C> Safe<T, C> {
    /// Create a new `Safe` value.
    pub fn new(value: T) -> Self {
        Safe(value, PhantomData)
    }

    /// Extract the inner value.
    pub fn into_inner(self) -> T {
        self.0
    }
}

/// Tensor placeholder with shape information.
///
/// In full implementation, shape will be encoded as const generics.
/// For Sprint 1, this is a simple wrapper.
#[derive(Debug, Clone, Copy)]
pub struct Tensor<T>(pub T);

// ============================================================================
// Pipeline trait
// ============================================================================

/// Trait implemented by all pipelines (generated by the `pipeline!` macro).
///
/// You should not implement this manually.
pub trait Pipeline {
    /// The input data type for this pipeline.
    type Input: Send + Sync + 'static;

    /// Returns the human-readable name of the pipeline.
    fn name(&self) -> &'static str;
}
