diff options
Diffstat (limited to 'lib/net/hippie/rust_backend.rb')
| -rw-r--r-- | lib/net/hippie/rust_backend.rb | 141 |
1 files changed, 138 insertions, 3 deletions
diff --git a/lib/net/hippie/rust_backend.rb b/lib/net/hippie/rust_backend.rb index 7d1637e..d25abf7 100644 --- a/lib/net/hippie/rust_backend.rb +++ b/lib/net/hippie/rust_backend.rb @@ -2,10 +2,57 @@ module Net module Hippie - # Rust backend integration + # Rust backend integration and availability detection. + # + # The RustBackend module manages the optional high-performance Rust HTTP client + # backend. It provides automatic detection of Rust extension availability and + # environment-based enabling/disabling of the Rust backend. + # + # == Backend Selection Logic + # + # 1. Check if NET_HIPPIE_RUST environment variable is set to 'true' + # 2. Verify that the Rust extension (net_hippie_ext) can be loaded + # 3. If both conditions are met, use RustConnection + # 4. Otherwise, fall back to RubyConnection + # + # == Performance Benefits + # + # When enabled, the Rust backend provides: + # * Significantly faster HTTP requests using reqwest + # * Better concurrency with Tokio async runtime + # * Lower memory usage with zero-cost abstractions + # * Type safety with compile-time guarantees + # + # @since 2.0.0 + # + # == Environment Configuration + # + # # Enable Rust backend + # ENV['NET_HIPPIE_RUST'] = 'true' + # + # # Check availability and status + # puts "Rust available: #{Net::Hippie::RustBackend.available?}" + # puts "Rust enabled: #{Net::Hippie::RustBackend.enabled?}" + # + # @see RUST_BACKEND.md Detailed setup and usage documentation module RustBackend @rust_available = nil + # Checks if the Rust extension is available for loading. + # + # This method attempts to require the 'net_hippie_ext' native extension + # and caches the result. The extension is built from Rust source code + # using Magnus for Ruby-Rust integration. + # + # @return [Boolean] true if Rust extension loaded successfully + # @since 2.0.0 + # + # @example Check Rust availability + # if Net::Hippie::RustBackend.available? + # puts "Rust backend ready!" + # else + # puts "Using Ruby backend (Rust not available)" + # end def self.available? return @rust_available unless @rust_available.nil? @@ -17,30 +64,102 @@ module Net end end + # Checks if the Rust backend is both available and enabled. + # + # Returns true only when: + # 1. NET_HIPPIE_RUST environment variable is set to 'true' + # 2. The Rust extension is available (compiled and loadable) + # + # @return [Boolean] true if Rust backend should be used + # @since 2.0.0 + # + # @example Check if Rust backend will be used + # ENV['NET_HIPPIE_RUST'] = 'true' + # if Net::Hippie::RustBackend.enabled? + # puts "All HTTP requests will use Rust backend" + # else + # puts "Falling back to Ruby backend" + # end def self.enabled? ENV['NET_HIPPIE_RUST'] == 'true' && available? end - # Adapter to make RustResponse behave like Net::HTTPResponse + # Adapter that makes Rust HTTP responses compatible with Net::HTTPResponse interface. + # + # The ResponseAdapter provides a compatibility layer between Rust HTTP responses + # and Ruby's Net::HTTPResponse objects. This ensures that existing code works + # unchanged when switching between Ruby and Rust backends. + # + # == Compatibility Features + # + # * Status code access via #code method + # * Response body access via #body method + # * Header access via #[] method + # * Response class detection via #class method + # * Type checking via #is_a? and #kind_of? + # + # @since 2.0.0 + # + # == Supported Response Classes + # + # * Net::HTTPOK (200) + # * Net::HTTPCreated (201) + # * Net::HTTPRedirection (3xx) + # * Net::HTTPClientError (4xx) + # * Net::HTTPServerError (5xx) + # + # @see Net::HTTPResponse The Ruby standard library response interface class ResponseAdapter + # Creates a new response adapter from a Rust HTTP response. + # + # @param rust_response [RustResponse] The Rust HTTP response object + # @since 2.0.0 def initialize(rust_response) @rust_response = rust_response @code = rust_response.code @body = rust_response.body end + # Returns the HTTP status code. + # + # @return [String] HTTP status code (e.g., "200", "404") + # @since 2.0.0 def code @code end + # Returns the response body content. + # + # @return [String] HTTP response body + # @since 2.0.0 def body @body end + # Retrieves a response header value by name. + # + # @param header_name [String, Symbol] Header name (case-insensitive) + # @return [String, nil] Header value or nil if not found + # @since 2.0.0 + # + # @example Get content type + # content_type = response['Content-Type'] + # location = response[:location] def [](header_name) @rust_response[header_name.to_s] end + # Returns the appropriate Net::HTTP response class based on status code. + # + # Maps HTTP status codes to their corresponding Net::HTTP class constants + # to maintain compatibility with Ruby HTTP library expectations. + # + # @return [Class] Net::HTTP response class constant + # @since 2.0.0 + # + # @example Check response type + # response.class # => Net::HTTPOK (for 200 status) + # response.class # => Net::HTTPNotFound (for 404 status) def class case @code.to_i when 200 @@ -58,11 +177,27 @@ module Net end end - # Make it behave like the expected response class + # Checks if this response is an instance of the given class. + # + # Provides compatibility with Ruby's type checking by delegating + # to the mapped response class while supporting normal inheritance. + # + # @param klass [Class] Class to check against + # @return [Boolean] true if response matches the class + # @since 2.0.0 + # + # @example Type checking + # response.is_a?(Net::HTTPOK) # => true (for 200 status) + # response.is_a?(Net::HTTPRedirection) # => true (for 3xx status) def is_a?(klass) self.class == klass || super end + # Alias for #is_a? to maintain Ruby compatibility. + # + # @param klass [Class] Class to check against + # @return [Boolean] true if response matches the class + # @since 2.0.0 def kind_of?(klass) is_a?(klass) end |
