Tracked under #6.
Scope
Context::new(path, params) is the only constructor today. Add support for loading a model from an in-memory buffer or via a custom whisper_model_loader.
Symbols
whisper_init_from_buffer_with_params — load from &[u8].
whisper_init_with_params — load via a user-supplied whisper_model_loader callback struct.
whisper_model_loader (the callback struct itself: read / eof / close).
Why deferred
Both add lifetime / ownership complexity:
- Buffer load: the bytes need to outlive the load call but don't need to outlive the Context (whisper.cpp copies into its arena). API choice:
&[u8] (borrowed for the call) vs Vec<u8> (owned, dropped after). Not hard, just hasn't been needed.
- Custom loader: the
whisper_model_loader struct holds three function pointers + opaque context. Wrapping it ergonomically means a WhisperLoader trait + a C trampoline per method (similar to the abort-callback pattern). Larger surface, narrower use case (rare to need a custom loader vs buffer or path).
No caller has asked for either.
Acceptance
Buffer load is the smaller deliverable:
Context::from_buffer(bytes: &[u8], params: ContextParams) -> WhisperResult<Self>.
- Same RAII / leak guarantees as
Context::new.
- Audit-matrix row.
- Tests on a small in-memory model fixture.
Custom loader is a separate, larger deliverable:
WhisperLoader trait (fn read(&mut self, buf: &mut [u8]) -> io::Result<usize>; fn eof(&self) -> bool; fn close(&mut self);).
- C trampolines for each.
Context::from_loader(impl WhisperLoader, params) -> WhisperResult<Self>.
Probably one PR for buffer load, a second for custom loader.
If you have a use case for either (sandboxed model loading, network-streamed model bytes, model-in-an-archive), drop a comment.
Tracked under #6.
Scope
Context::new(path, params)is the only constructor today. Add support for loading a model from an in-memory buffer or via a customwhisper_model_loader.Symbols
whisper_init_from_buffer_with_params— load from&[u8].whisper_init_with_params— load via a user-suppliedwhisper_model_loadercallback struct.whisper_model_loader(the callback struct itself:read/eof/close).Why deferred
Both add lifetime / ownership complexity:
&[u8](borrowed for the call) vsVec<u8>(owned, dropped after). Not hard, just hasn't been needed.whisper_model_loaderstruct holds three function pointers + opaque context. Wrapping it ergonomically means aWhisperLoadertrait + a C trampoline per method (similar to the abort-callback pattern). Larger surface, narrower use case (rare to need a custom loader vs buffer or path).No caller has asked for either.
Acceptance
Buffer load is the smaller deliverable:
Context::from_buffer(bytes: &[u8], params: ContextParams) -> WhisperResult<Self>.Context::new.Custom loader is a separate, larger deliverable:
WhisperLoadertrait (fn read(&mut self, buf: &mut [u8]) -> io::Result<usize>; fn eof(&self) -> bool; fn close(&mut self);).Context::from_loader(impl WhisperLoader, params) -> WhisperResult<Self>.Probably one PR for buffer load, a second for custom loader.
If you have a use case for either (sandboxed model loading, network-streamed model bytes, model-in-an-archive), drop a comment.