Skip to main content

HsPipeline

Struct HsPipeline 

Source
pub struct HsPipeline { /* private fields */ }
Expand description

Main HS code classification pipeline.

§Example — direct (sync)

use hs_predict::pipeline::HsPipeline;
use hs_predict::types::{ProductDescription, SubstanceIdentifier, PhysicalForm};

let pipeline = HsPipeline::new();

let product = ProductDescription {
    identifier: SubstanceIdentifier::from_cas("1310-73-2"),
    physical_form: Some(PhysicalForm::Solid),
    purity_pct: None,
    purity_type: None,
    mixture_components: None,
    intended_use: None,
    additional_context: None,
};

let prediction = pipeline.classify(&product).unwrap();
assert_eq!(&prediction.hs_code, "281511");

§Example — with PubChem enrichment (async, pubchem feature)

use hs_predict::pipeline::HsPipeline;
use hs_predict::pubchem::PubChemClient;
use hs_predict::types::{ProductDescription, SubstanceIdentifier, PhysicalForm};

let pipeline = HsPipeline::new().with_pubchem(PubChemClient::new());

let mut product = ProductDescription {
    identifier: SubstanceIdentifier::from_cas("1310-73-2"),
    physical_form: Some(PhysicalForm::Solid),
    purity_pct: None,
    purity_type: None,
    mixture_components: None,
    intended_use: None,
    additional_context: None,
};

pipeline.enrich(&mut product).await?;   // fills SMILES, InChI, IUPAC name …
let prediction = pipeline.classify(&product)?;
println!("{}", prediction.display());   // "28.15.11"

§Example — with LLM fallback (async, llm feature)

use hs_predict::pipeline::HsPipeline;
use hs_predict::llm::{LlmClassifier, LlmPrompt, LlmResponse};
use futures::future::BoxFuture;

struct MyClient;
impl LlmClassifier for MyClient {
    fn classify<'a>(&'a self, prompt: &'a LlmPrompt) -> BoxFuture<'a, hs_predict::Result<LlmResponse>> {
        Box::pin(async move { todo!() })
    }
}

let pipeline = HsPipeline::new().with_llm(MyClient);
use hs_predict::types::{ProductDescription, SubstanceIdentifier};
let product = ProductDescription {
    identifier: SubstanceIdentifier::from_cas("12-34-5"),
    physical_form: None, purity_pct: None, purity_type: None,
    mixture_components: None, intended_use: None, additional_context: None,
};
let prediction = pipeline.classify_with_llm(&product).await?;
println!("{}", prediction.display());

Implementations§

Source§

impl HsPipeline

Source

pub fn new() -> Self

Create a pipeline with default configuration.

Source

pub fn with_mapping( self, cas: impl Into<String>, hs_code: impl Into<String>, ) -> Self

Add a user-provided CAS → HS code mapping.

These mappings override the embedded rule table with confidence = 1.0.

Source

pub fn with_config(self, config: PipelineConfig) -> Self

Override the default pipeline configuration.

Source

pub fn with_llm(self, client: impl LlmClassifier + 'static) -> Self

Attach an LlmClassifier implementation to enable the LLM fallback (Priority 4).

The LLM is called by classify_with_llm when the rule-based pipeline returns a result with recommended_action != Accept, or returns LowConfidenceNoLlm.

Requires the llm Cargo feature.

Source

pub fn with_pubchem(self, client: PubChemClient) -> Self

Attach a PubChemClient to enable automatic identifier enrichment before classification.

Requires the pubchem Cargo feature.

Source

pub async fn enrich(&self, product: &mut ProductDescription) -> Result<()>

Enrich a ProductDescription with PubChem data.

Fills in any missing fields of the main identifier and each mixture component’s identifier (SMILES, InChI, InChIKey, IUPAC name, CID).

This is a best-effort operation:

  • “Not found” and “no usable identifier” results are silently ignored.
  • Network / parse errors are propagated.
  • If no PubChem client is configured, returns Ok(()) immediately.

Requires the pubchem Cargo feature.

Source

pub fn classify(&self, product: &ProductDescription) -> Result<HsPrediction>

Classify a product and return an HS code prediction.

Priority order:

  1. User-provided mapping
  2. Embedded static rule table
  3. (v0.3) SMILES rule engine
  4. (v0.4) LLM fallback
Source

pub async fn classify_with_llm( &self, product: &ProductDescription, ) -> Result<HsPrediction>

Classify a product, falling back to the configured LLM when the rule-based pipeline returns a low-confidence or uncertain result.

§Priority order (same as classify + LLM)
  1. User-provided mapping → Accept → return immediately.
  2. Embedded static rule table → Accept → return immediately.
  3. SMILES rule engine → Accept → return immediately.
  4. Any result with recommended_action != Accept, or LowConfidenceNoLlm → forward to LLM.

If no LLM client has been configured via with_llm, returns HsPredictError::LlmNotConfigured.

§Validation

The LLM’s hs_code must be exactly 6 ASCII digits; otherwise HsPredictError::ValidationFailed is returned.

§Chapter consistency

If the LLM chapter differs from the SMILES engine’s chapter hint, a warning note is appended — this is not a hard error.

Requires the llm Cargo feature.

Trait Implementations§

Source§

impl Debug for HsPipeline

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for HsPipeline

Source§

fn default() -> HsPipeline

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more