Commit 6a6477c0 authored by Meade's avatar Meade

Complete rewrite in Rust, redesign, and additional features added.

parent 29ba5b3f
*.gem
*.rbc
/.config
/coverage/
/InstalledFiles
/pkg/
/spec/reports/
/spec/examples.txt
/test/tmp/
/test/version_tmp/
/tmp/
# Used by dotenv library to load environment variables.
# .env
## Specific to RubyMotion:
.dat*
.repl_history
build/
*.bridgesupport
build-iPhoneOS/
build-iPhoneSimulator/
## Specific to RubyMotion (use of CocoaPods):
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
# vendor/Pods/
## Documentation cache and generated files:
/.yardoc/
/_yardoc/
/doc/
/rdoc/
## Environment normalization:
/.bundle/
/vendor/bundle
/lib/bundler/man/
# for a library or gem, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# Gemfile.lock
# .ruby-version
# .ruby-gemset
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
.rvmrc
# GTK/Glade stuffs
*.glade~
\ No newline at end of file
/target/
**/*.rs.bk
\ No newline at end of file
This diff is collapsed.
require 'gtk3'
require_relative 'guestimateABV'
require_relative 'increaseABV'
require_relative 'realABV'
require_relative 'waterSparge'
gladeFile = 'BrewStillery.glade'
# Construct a Gtk::Builder instance and load our UI description
$builder = Gtk::Builder.new
$builder.add_from_file(gladeFile)
# appID = Gtk::Application.new("in.monkeylog.BrewStillery", :flags_none)
# appID.signal_connect "activate" do |application|
# mainWindow = Gtk::ApplicationWindow.new(application)
# end
# strip the mainWindow line out of the bullshit
mainWindow = $builder.get_object("mainWindow")
mainWindow.signal_connect("destroy") { Gtk.main_quit }
# Connect signal handlers to the constructed widgets
guestimateABV
# call method from guestimateABV.rb
increaseABV
# call method from increaseABV.rb
realABV
# call method from realABV.rb
waterSparge
# call method from waterSparge.rb
mainWindow = $builder.get_object('mainWindow')
mainWindow.set_title("BrewStillery")
mainWindow.show()
Gtk.main
\ No newline at end of file
This diff is collapsed.
[package]
name = "BrewStillery"
version = "1.0.0"
authors = ["Emily And Meade <thedarkula2049@gmail.com>"]
[dependencies]
regex = "0.2.2"
[dependencies.gtk]
version = "0.2.0"
features = ["v3_22"]
[profile.dev]
codegen-units = 4
[profile.release]
opt-level = 3
codegen-units = 4
\ No newline at end of file
# BrewStillery
An all-in-one beer, wine, and spirits tool
An all-in-one beer, wine, and spirits tool.
Written in Rust and GTK3
......
Calculators to add:
grain
water chemistry
IBU
\ No newline at end of file
def guestimateABV
def beerGuestimatorSettings
@guestimatorInput = $builder.get_object("guestimatorInputBeer")
@guestimatorOutput = "guestimatorOutputBeer"
guestiMaths
end
buttonBeer = $builder.get_object("guestimatorButtonBeer")
buttonBeer.signal_connect("clicked") {
beerGuestimatorSettings
}
guestimatorInputBeer = $builder.get_object("guestimatorInputBeer")
guestimatorInputBeer.signal_connect("activate") {
beerGuestimatorSettings
}
def wineGuestimatorSettings
@guestimatorInput = $builder.get_object("guestimatorInputWine")
@guestimatorOutput = "guestimatorOutputWine"
guestiMaths
end
buttonWine = $builder.get_object("guestimatorButtonWine")
buttonWine.signal_connect("clicked") {
wineGuestimatorSettings
}
guestimatorInputWine = $builder.get_object("guestimatorInputWine")
guestimatorInputWine.signal_connect("activate") {
wineGuestimatorSettings
}
def champagneGuestimatorSettings
@guestimatorInput = $builder.get_object("guestimatorInputChampagne")
@guestimatorOutput = "guestimatorOutputChampagne"
guestiMaths
end
buttonChampagne = $builder.get_object("guestimatorButtonChampagne")
buttonChampagne.signal_connect("clicked") {
champagneGuestimatorSettings
}
guestimatorInputChampagne = $builder.get_object("guestimatorInputChampagne")
guestimatorInputChampagne.signal_connect("activate") {
champagneGuestimatorSettings
}
def spiritsGuestimatorSettings
@guestimatorInput = $builder.get_object("guestimatorInputSpirits")
@guestimatorOutput = "guestimatorOutputSpirits"
guestiMaths
end
buttonSpirits = $builder.get_object("guestimatorButtonSpirits")
buttonSpirits.signal_connect("clicked") {
spiritsGuestimatorSettings
}
guestimatorInputSpirits = $builder.get_object("guestimatorInputSpirits")
guestimatorInputSpirits.signal_connect("activate") {
spiritsGuestimatorSettings
}
end
def guestiMaths
# when the button is clicked or enter/return is pressed, do the following:
startingBrix = @guestimatorInput.text.to_f
originalGravity = (startingBrix / (258.6 - ((startingBrix / 258.2) * 227.1))) + 1
finalGravity = 1.015
originalExtract = (-668.962) + (1262.45 * originalGravity ) - (776.43 * originalGravity**2) + (182.94 * originalGravity**3)
apparentExtract = (-668.962) + (1262.45 * finalGravity ) - (776.43 * finalGravity**2) + (182.94 * finalGravity**3)
attenuationCoefficient = (0.22) + (0.001 * originalExtract)
realExtract = ((attenuationCoefficient * originalExtract) + apparentExtract) / (1 + attenuationCoefficient)
# realAttenuation = ((originalExtract - realExtract) / originalExtract) * 100
# puts 'Your Real Attenuation is: ' + realAttenuation.round(2).to_s + '%'
estimatedABW = (originalExtract - realExtract) / ( 2.0665 - (0.010665 * originalExtract))
estimatedABV = estimatedABW * (finalGravity / 0.794)
abv = estimatedABV.round(2).to_s + '%'
output = $builder.get_object @guestimatorOutput
# set the variable 'output' to be the text of the widget "guestimatorOutput"
output.set_text(abv)
# write the result of the above maths (variable 'abv') to the text of the widget "guestimatorOutput"
end
\ No newline at end of file
def increaseABV
def beerIncreaseSettings
@increaseABVBrixInput = $builder.get_object("increaseABVBrixInputBeer")
@increaseABVABVInput = $builder.get_object("increaseABVABVInputBeer")
@increaseABVVolumeInput = $builder.get_object("increaseABVVolumeInputBeer")
@switch = $builder.get_object("imperialOrMetricSwitchSugarBeer")
@increaseABVNewBrix = $builder.get_object("increaseABVNewBrixBeer")
@increaseABVEstimatedABV = $builder.get_object("increaseABVEstimatedABVBeer")
@sugarAddOutput = $builder.get_object("sugarAddOutputBeer")
@honeyAddOutput = $builder.get_object("honeyAddOutputBeer")
onSwitchActivatedSugar
end
buttonBeer = $builder.get_object("increaseABVButtonBeer")
buttonBeer.signal_connect("clicked") {
beerIncreaseSettings
}
increaseABVBrixInputBeer = $builder.get_object("increaseABVBrixInputBeer")
increaseABVBrixInputBeer.signal_connect("activate") {
beerIncreaseSettings
}
increaseABVABVInputBeer = $builder.get_object("increaseABVABVInputBeer")
increaseABVABVInputBeer.signal_connect("activate") {
beerIncreaseSettings
}
increaseABVVolumeInputBeer = $builder.get_object("increaseABVVolumeInputBeer")
increaseABVVolumeInputBeer.signal_connect("activate") {
beerIncreaseSettings
}
def wineIncreaseSettings
@increaseABVBrixInput = $builder.get_object("increaseABVBrixInputWine")
@increaseABVABVInput = $builder.get_object("increaseABVABVInputWine")
@increaseABVVolumeInput = $builder.get_object("increaseABVVolumeInputWine")
@switch = $builder.get_object("imperialOrMetricSwitchSugarWine")
@increaseABVNewBrix = $builder.get_object("increaseABVNewBrixWine")
@increaseABVEstimatedABV = $builder.get_object("increaseABVEstimatedABVWine")
@sugarAddOutput = $builder.get_object("sugarAddOutputWine")
@honeyAddOutput = $builder.get_object("honeyAddOutputWine")
onSwitchActivatedSugar
end
buttonWine = $builder.get_object("increaseABVButtonWine")
buttonWine.signal_connect("clicked") {
wineIncreaseSettings
}
increaseABVBrixInputWine = $builder.get_object("increaseABVBrixInputWine")
increaseABVBrixInputWine.signal_connect("activate") {
wineIncreaseSettings
}
increaseABVABVInputWine = $builder.get_object("increaseABVABVInputWine")
increaseABVABVInputWine.signal_connect("activate") {
wineIncreaseSettings
}
increaseABVVolumeInputWine = $builder.get_object("increaseABVVolumeInputWine")
increaseABVVolumeInputWine.signal_connect("activate") {
wineIncreaseSettings
}
def champagneIncreaseSettings
@increaseABVBrixInput = $builder.get_object("increaseABVBrixInputChampagne")
@increaseABVABVInput = $builder.get_object("increaseABVABVInputChampagne")
@increaseABVVolumeInput = $builder.get_object("increaseABVVolumeInputChampagne")
@switch = $builder.get_object("imperialOrMetricSwitchSugarChampagne")
@increaseABVNewBrix = $builder.get_object("increaseABVNewBrixChampagne")
@increaseABVEstimatedABV = $builder.get_object("increaseABVEstimatedABVChampagne")
@sugarAddOutput = $builder.get_object("sugarAddOutputChampagne")
@honeyAddOutput = $builder.get_object("honeyAddOutputChampagne")
onSwitchActivatedSugar
end
buttonChampagne = $builder.get_object("increaseABVButtonChampagne")
buttonChampagne.signal_connect("clicked") {
champagneIncreaseSettings
}
increaseABVBrixInputChampagne = $builder.get_object("increaseABVBrixInputChampagne")
increaseABVBrixInputChampagne.signal_connect("activate") {
champagneIncreaseSettings
}
increaseABVABVInputChampagne = $builder.get_object("increaseABVABVInputChampagne")
increaseABVABVInputChampagne.signal_connect("activate") {
champagneIncreaseSettings
}
increaseABVVolumeInputChampagne = $builder.get_object("increaseABVVolumeInputChampagne")
increaseABVVolumeInputChampagne.signal_connect("activate") {
champagneIncreaseSettings
}
def spiritsIncreaseSettings
@increaseABVBrixInput = $builder.get_object("increaseABVBrixInputSpirits")
@increaseABVABVInput = $builder.get_object("increaseABVABVInputSpirits")
@increaseABVVolumeInput = $builder.get_object("increaseABVVolumeInputSpirits")
@switch = $builder.get_object("imperialOrMetricSwitchSugarSpirits")
@increaseABVNewBrix = $builder.get_object("increaseABVNewBrixSpirits")
@increaseABVEstimatedABV = $builder.get_object("increaseABVEstimatedABVSpirits")
@sugarAddOutput = $builder.get_object("sugarAddOutputSpirits")
@honeyAddOutput = $builder.get_object("honeyAddOutputSpirits")
onSwitchActivatedSugar
end
buttonSpirits = $builder.get_object("increaseABVButtonSpirits")
buttonSpirits.signal_connect("clicked") {
spiritsIncreaseSettings
}
increaseABVBrixInputSpirits = $builder.get_object("increaseABVBrixInputSpirits")
increaseABVBrixInputSpirits.signal_connect("activate") {
spiritsIncreaseSettings
}
increaseABVABVInputSpirits = $builder.get_object("increaseABVABVInputSpirits")
increaseABVABVInputSpirits.signal_connect("activate") {
spiritsIncreaseSettings
}
increaseABVVolumeInputSpirits = $builder.get_object("increaseABVVolumeInputSpirits")
increaseABVVolumeInputSpirits.signal_connect("activate") {
spiritsIncreaseSettings
}
end
def onSwitchActivatedSugar
# to determine if imperial or metric so to use the correct measurements and calculations
if @switch.active? == true
differenceBrixMaths
sugarToAddMetric = ((@desiredWortVolume / 3.78541) * 1.5 * @newEstimatedABV) * 0.0283495
honeyToAddMetric = sugarToAddMetric * 1.250001102
newSB = @newStartingBrix.round(2).to_s + '°Bx'
newABV = @newEstimatedABV.round(2).to_s + '%'
sugar = sugarToAddMetric.round(2).to_s + ' kilos'
honey = honeyToAddMetric.round(2).to_s + ' kilos'
elsif @switch.active? == false
differenceBrixMaths
sugarToAddImperial = (@desiredWortVolume * 1.5 * @newEstimatedABV) / 16
honeyToAddImperial = sugarToAddImperial * 1.25
newSB = @newStartingBrix.round(2).to_s + '°Bx'
newABV = @newEstimatedABV.round(2).to_s + '%'
sugar = sugarToAddImperial.to_i.to_s + ' lbs ' + (sugarToAddImperial % 1 * 16).to_i.to_s + ' oz'
honey = honeyToAddImperial.to_i.to_s + ' lbs ' + (honeyToAddImperial % 1 * 16).to_i.to_s + ' oz'
end
# set the output variables to be the text of each widget
# write the result of the above maths to the text of each widget
@increaseABVNewBrix.set_text(newSB)
@increaseABVEstimatedABV.set_text(newABV)
@sugarAddOutput.set_text(sugar)
@honeyAddOutput.set_text(honey)
end
def differenceBrixMaths
# to calculate the difference in Brix, which is the same for both imperial and metric
startingBrix = @increaseABVBrixInput.text.to_f
desiredABV = @increaseABVABVInput.text.to_f
@desiredWortVolume = @increaseABVVolumeInput.text.to_f
finalGravity = 1.015
originalExtract = (-((513.11767463 * desiredABV + 59931.43605250) - (46882.32536333 * (Math.sqrt(0.00022734 * desiredABV**2 + 0.02819081 * desiredABV + 1.63414684)))) / desiredABV)
originalGravity = 1.00001 + 0.0038661 * originalExtract + 1.3488 * 10**(-5) * originalExtract**2 + 4.3074 * 10**(-8) * originalExtract**3
@newStartingBrix = (258.6 * originalGravity - 258.6) / (0.87955073 * originalGravity + 0.12044926)
apparentExtract = (-668.962) + (1262.45 * finalGravity ) - (776.43 * finalGravity**2) + (182.94 * finalGravity**3)
attenuationCoefficient = (0.22) + (0.001 * originalExtract)
realExtract = ((attenuationCoefficient * originalExtract) + apparentExtract) / (1 + attenuationCoefficient)
estimatedABW = (originalExtract - realExtract) / ( 2.0665 - (0.010665 * originalExtract))
@newEstimatedABV = estimatedABW * (finalGravity / 0.794)
@newEstimatedABV = @newStartingBrix - startingBrix
end
\ No newline at end of file
def realABV
def beerRealSettings
@realABVStartingBrixInput = $builder.get_object("realABVStartingBrixInputBeer")
@realABVFinalBrixInput = $builder.get_object("realABVFinalBrixInputBeer")
@realABVFinalAttenuation = $builder.get_object("realABVFinalAttenuationBeer")
@realABVFinalABV = $builder.get_object("realABVFinalABVBeer")
realABVMaths
end
buttonBeer = $builder.get_object("realABVButtonBeer")
buttonBeer.signal_connect("clicked") {
beerRealSettings
}
realABVStartingBrixInputBeer = $builder.get_object("realABVStartingBrixInputBeer")
realABVStartingBrixInputBeer.signal_connect("activate") {
beerRealSettings
}
realABVFinalBrixInputBeer = $builder.get_object("realABVFinalBrixInputBeer")
realABVFinalBrixInputBeer.signal_connect("activate") {
beerRealSettings
}
def wineRealSettings
@realABVStartingBrixInput = $builder.get_object("realABVStartingBrixInputWine")
@realABVFinalBrixInput = $builder.get_object("realABVFinalBrixInputWine")
@realABVFinalAttenuation = $builder.get_object("realABVFinalAttenuationWine")
@realABVFinalABV = $builder.get_object("realABVFinalABVWine")
realABVMaths
end
buttonWine = $builder.get_object("realABVButtonWine")
buttonWine.signal_connect("clicked") {
wineRealSettings
}
realABVStartingBrixInputWine = $builder.get_object("realABVStartingBrixInputWine")
realABVStartingBrixInputWine.signal_connect("activate") {
wineRealSettings
}
realABVFinalBrixInputWine = $builder.get_object("realABVFinalBrixInputWine")
realABVFinalBrixInputWine.signal_connect("activate") {
wineRealSettings
}
def champagneRealSettings
@realABVStartingBrixInput = $builder.get_object("realABVStartingBrixInputChampagne")
@realABVFinalBrixInput = $builder.get_object("realABVFinalBrixInputChampagne")
@realABVFinalAttenuation = $builder.get_object("realABVFinalAttenuationChampagne")
@realABVFinalABV = $builder.get_object("realABVFinalABVChampagne")
realABVMaths
end
buttonChampagne = $builder.get_object("realABVButtonChampagne")
buttonChampagne.signal_connect("clicked") {
champagneRealSettings
}
realABVStartingBrixInputChampagne = $builder.get_object("realABVStartingBrixInputChampagne")
realABVStartingBrixInputChampagne.signal_connect("activate") {
champagneRealSettings
}
realABVFinalBrixInputChampagne = $builder.get_object("realABVFinalBrixInputChampagne")
realABVFinalBrixInputChampagne.signal_connect("activate") {
champagneRealSettings
}
def spiritsRealSettings
@realABVStartingBrixInput = $builder.get_object("realABVStartingBrixInputSpirits")
@realABVFinalBrixInput = $builder.get_object("realABVFinalBrixInputSpirits")
@realABVFinalAttenuation = $builder.get_object("realABVFinalAttenuationSpirits")
@realABVFinalABV = $builder.get_object("realABVFinalABVSpirits")
realABVMaths
end
buttonSpirits = $builder.get_object("realABVButtonSpirits")
buttonSpirits.signal_connect("clicked") {
spiritsRealSettings
}
realABVStartingBrixInputSpirits = $builder.get_object("realABVStartingBrixInputSpirits")
realABVStartingBrixInputSpirits.signal_connect("activate") {
spiritsRealSettings
}
realABVFinalBrixInputSpirits = $builder.get_object("realABVFinalBrixInputSpirits")
realABVFinalBrixInputSpirits.signal_connect("activate") {
spiritsRealSettings
}
end
def realABVMaths
startingBrix = @realABVStartingBrixInput.text.to_f
finalBrix = @realABVFinalBrixInput.text.to_f
originalGravity = (startingBrix / (258.6 - ((startingBrix / 258.2) * 227.1))) + 1
finalGravity = (finalBrix / (258.6 - ((finalBrix / 258.2) * 227.1))) + 1
originalExtract = (-668.962) + (1262.45 * originalGravity) - (776.43 * originalGravity**2) + (182.94 * originalGravity**3)
apparentExtract = (-668.962) + (1262.45 * finalGravity) - (776.43 * finalGravity**2) + (182.94 * finalGravity**3)
attenuationCoefficient = (0.22) + (0.001 * originalExtract)
realExtract = (attenuationCoefficient * originalExtract + apparentExtract) / (1 + attenuationCoefficient)
realAttenuation = ((originalExtract - realExtract) / originalExtract) * 100
attenuation = realAttenuation.round(2).to_s + '%'
@realABVFinalAttenuation.set_text(attenuation)
estimatedABW = (originalExtract - realExtract) / ( 2.0665 - (0.010665 * originalExtract))
finalABV = estimatedABW * (finalGravity / 0.794)
abv = finalABV.round(2).to_s + '%'
@realABVFinalABV.set_text(abv)
end
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
#![allow(non_snake_case)]
use gtk::{self};
use gtk::prelude::*;
use regex::Regex;
pub fn champagneCarbonationPrep(ref champagneCarbonationBuilderClone: &gtk::Builder) {
let champagneCarbonationInput: &gtk::Entry = &champagneCarbonationBuilderClone.get_object("champagneCarbonationInput").unwrap();
let champagneCarbonationInputBuffer = champagneCarbonationInput.get_text().expect("No input");
let champagneCarbonationOutput = String::from("champagneCarbonationOutput");
let isNumerical = Regex::new(r"^\d+\.\d+|\d+$").unwrap();
let isCharacter = Regex::new(r"^\D$").unwrap();
let isMismatched = Regex::new(r"^\d+\D+|\d+\D+\d+$").unwrap();
if champagneCarbonationInputBuffer == "" || isNumerical.is_match(&champagneCarbonationInputBuffer) == false || isCharacter.is_match(&champagneCarbonationInputBuffer) == true || isMismatched.is_match(&champagneCarbonationInputBuffer) == true {
let output: gtk::Entry = champagneCarbonationBuilderClone.get_object(&champagneCarbonationOutput).unwrap();
output.set_text("Enter a number");
} else {
let champagneCarbonationInputBufferFloat: f32 = champagneCarbonationInputBuffer.parse().unwrap();
if champagneCarbonationInputBufferFloat <= 0.0 {
let output: gtk::Entry = champagneCarbonationBuilderClone.get_object(&champagneCarbonationOutput).unwrap();
output.set_text("Enter a positive number");
} else {
onChampagneActivate(champagneCarbonationInputBuffer, &champagneCarbonationBuilderClone);
}
}
}
pub fn onChampagneActivate(champagneCarbonationInputBuffer: String, ref champagneCarbonationBuilderClone: &gtk::Builder) {
let ref champagneCarbonationSwitch: &gtk::Switch = &champagneCarbonationBuilderClone.get_object("champagneCarbonationSwitch").unwrap();
let champagneVolume: f32 = champagneCarbonationInputBuffer.parse().unwrap();
if champagneCarbonationSwitch.get_active() == true {
let imperialOrMetric = String::from("metric");
champagneCarbonationMaths(champagneVolume, imperialOrMetric, &champagneCarbonationBuilderClone);
} else if champagneCarbonationSwitch.get_active() == false {
let imperialOrMetric = String::from("imperial");
champagneCarbonationMaths(champagneVolume, imperialOrMetric, &champagneCarbonationBuilderClone);
}
}
fn champagneCarbonationMaths(champagneVolume: f32, imperialOrMetric: String, ref champagneCarbonationBuilderClone: &gtk::Builder) {
let ref champagneCarbonationOutput: &gtk::Entry = &champagneCarbonationBuilderClone.get_object("champagneCarbonationOutput").unwrap();
if imperialOrMetric == "imperial" {
let totalSugar = champagneVolume * 0.2;
if totalSugar == 1.0 {
let sugar = format!("{:.0} pound", totalSugar);
champagneCarbonationOutput.set_text(&sugar);
} else {
let sugar = format!("{:.2} pounds", totalSugar);
champagneCarbonationOutput.set_text(&sugar);
}
} else if imperialOrMetric == "metric" {
let totalSugar = (champagneVolume * 23.986897025) / 1000.0;
if totalSugar == 1.0 {
let sugar = format!("{:.0} kilo", totalSugar);
champagneCarbonationOutput.set_text(&sugar);
} else {
let sugar = format!("{:.2} kilos", totalSugar);
champagneCarbonationOutput.set_text(&sugar);
}
}
}
\ No newline at end of file
#![allow(non_snake_case)]
pub fn brixToGravity(brix: f32) -> f32 {
(brix / (258.6 - ((brix / 258.2) * 227.1))) + 1.0
}
pub fn gravityToPlato(gravity: f32) -> f32 {
135.997 * gravity.powi(3) - 630.272 * gravity.powi(2) + 1111.14 * gravity - 616.868
}
\ No newline at end of file
#![allow(non_snake_case)]
use gtk::{self};
use gtk::prelude::*;
use regex::Regex;
use functions::commonFunctions::*;
pub fn guestimatePrep(ref guestimatorBuilderClone: &gtk::Builder) {
let guestimatorInput: &gtk::Entry = &guestimatorBuilderClone.get_object("guestimatorInput").unwrap();
let buffer = guestimatorInput.get_text().expect("No input");
let guestimatorOutput = String::from("guestimatorOutput");
let isNumerical = Regex::new(r"^\d+\.\d+|\d+$").unwrap();
let isCharacter = Regex::new(r"^\D$").unwrap();
let isMismatched = Regex::new(r"^\d+\D+|\d+\D+\d+$").unwrap();
if buffer == "" || isNumerical.is_match(&buffer) == false || isCharacter.is_match(&buffer) == true || isMismatched.is_match(&buffer) == true {
let output: gtk::Entry = guestimatorBuilderClone.get_object(&guestimatorOutput).unwrap();
output.set_text("Enter a number");
} else {
let bufferFloat: f32 = buffer.parse().unwrap();
if bufferFloat < 3.83 {
let output: gtk::Entry = guestimatorBuilderClone.get_object(&guestimatorOutput).unwrap();
output.set_text("Enter a number greater than 3.83");
} else if bufferFloat > 49.48 {
let output: gtk::Entry = guestimatorBuilderClone.get_object(&guestimatorOutput).unwrap();
output.set_text("Enter a number less than 49.48");
} else {
guestiMaths(buffer, guestimatorOutput, &guestimatorBuilderClone);
}
}
}
pub fn guestiMaths(buffer: String, guestimatorOutput: String, ref guestimatorBuilderClone: &gtk::Builder) {
let startingBrix: f32 = buffer.parse().unwrap();
let originalGravity = brixToGravity(startingBrix);
let finalGravity: f32 = 1.015;
// since finalGravity is unknown, this constant is ideal
let originalExtract = (-668.962) + (1262.45 * originalGravity ) - (776.43 * originalGravity.powi(2)) + (182.94 * originalGravity.powi(3));
let apparentExtract = (-668.962) + (1262.45 * finalGravity ) - (776.43 * finalGravity.powi(2)) + (182.94 * finalGravity.powi(3));
let attenuationCoefficient = (0.22) + (0.001 * originalExtract);
let realExtract = ((attenuationCoefficient * originalExtract) + apparentExtract) / (1.0 + attenuationCoefficient);
// unneeded information, but here if we want it
//
// let realAttenuation = ((originalExtract - realExtract) / originalExtract) * 100.0;
// let realAttenuationRounded = format!("{:.2}", realAttenuation);
// println!("Your Real Attenuation is: {}", realAttenuationRounded);
let estimatedABW = (originalExtract - realExtract) / ( 2.0665 - (0.010665 * originalExtract));
let estimatedABV = estimatedABW * (finalGravity / 0.794);
let abv = format!("{:.2}", estimatedABV);
let ref output: &gtk::Entry = &guestimatorBuilderClone.get_object(&guestimatorOutput).unwrap();
output.set_text(&abv.to_string());
}
\ No newline at end of file
<
#![allow(non_snake_case)]
use gtk::{self};
use gtk::prelude::*;
use regex::Regex;
use functions::commonFunctions::*;
pub fn gyleCarbonationPrep(ref gyleBuilderClone: &gtk::Builder) {
let gyleBrixInput: &gtk::Entry = &gyleBuilderClone.get_object("gyleBrixInput").unwrap();
let gyleBrixInputBuffer = gyleBrixInput.get_text().expect("No input");
let gyleCO2Input: &gtk::Entry = &gyleBuilderClone.get_object("gyleCO2Input").unwrap();
let gyleCO2InputBuffer = gyleCO2Input.get_text().expect("No input");
let gyleFinalVolumeInput: &gtk::Entry = &gyleBuilderClone.get_object("gyleFinalVolumeInput").unwrap();
let gyleFinalVolumeInputBuffer = gyleFinalVolumeInput.get_text().expect("No input");
let spargeMashWaterOutput = String::from("spargeMashWaterOutput");
let isNumerical = Regex::new(r"^\d+\.\d+|\d+$").unwrap();
let isCharacter = Regex::new(r"^\D$").unwrap();
let isMismatched = Regex::new(r"^\d+\D+|\d+\D+\d+$").unwrap();
if gyleBrixInputBuffer == "" || isNumerical.is_match(&gyleBrixInputBuffer) == false || isCharacter.is_match(&gyleBrixInputBuffer) == true || isMismatched.is_match(&gyleBrixInputBuffer) == true {
let output: gtk::Entry = gyleBuilderClone.get_object(&spargeMashWaterOutput).unwrap();
output.set_text("Enter a number");
} else if gyleCO2InputBuffer == "" || isNumerical.is_match(&gyleCO2InputBuffer) == false || isCharacter.is_match(&gyleCO2InputBuffer) == true || isMismatched.is_match(&gyleCO2InputBuffer) == true {
let output: gtk::Entry = gyleBuilderClone.get_object(&spargeMashWaterOutput).unwrap();
output.set_text("Enter a number");
} else if gyleFinalVolumeInputBuffer == "" || isNumerical.is_match(&gyleFinalVolumeInputBuffer) == false || isCharacter.is_match(&gyleFinalVolumeInputBuffer) == true || isMismatched.is_match(&gyleFinalVolumeInputBuffer) == true {
let output: gtk::Entry = gyleBuilderClone.get_object(&spargeMashWaterOutput).unwrap();
output.set_text("Enter a number");
} else {
let gyleBrixInputBufferFloat: f32 = gyleBrixInputBuffer.parse().unwrap();
let gyleCO2InputBufferFloat: f32 = gyleCO2InputBuffer.parse().unwrap();
let gyleFinalVolumeInputBufferFloat: f32 = gyleFinalVolumeInputBuffer.parse().unwrap();
if gyleBrixInputBufferFloat <= 0.0 {
let output: gtk::Entry = gyleBuilderClone.get_object(&spargeMashWaterOutput).unwrap();
output.set_text("Enter a positive number");
} else if gyleCO2InputBufferFloat <= 0.0 {
let output: gtk::Entry = gyleBuilderClone.get_object(&spargeMashWaterOutput).unwrap();
output.set_text("Enter a positive number");
} else if gyleFinalVolumeInputBufferFloat <= 0.0 {
let output: gtk::Entry = gyleBuilderClone.get_object(&spargeMashWaterOutput).unwrap();
output.set_text("Enter a positive number");
} else {
onGyleActivate(gyleBrixInputBuffer, gyleCO2InputBuffer, gyleFinalVolumeInputBuffer, &gyleBuilderClone);
}
}
}
pub fn onGyleActivate(startingBrixBuffer: String, desiredCO2LevelBuffer: String, finalVolumeBuffer: String, ref gyleBuilderClone: &gtk::Builder) {
let ref gyleCarbonationSwitch: &gtk::Switch = &gyleBuilderClone.get_object("gyleCarbonationSwitch").unwrap();
let startingBrix: f32 = startingBrixBuffer.parse().unwrap();
let desiredCO2Level: f32 = desiredCO2LevelBuffer.parse().unwrap();
let finalVolume: f32 = finalVolumeBuffer.parse().unwrap();
if gyleCarbonationSwitch.get_active() == true {
let imperialOrMetric = String::from("metric");
gyleMaths(startingBrix, desiredCO2Level, finalVolume, imperialOrMetric, &gyleBuilderClone);
} else if gyleCarbonationSwitch.get_active() == false {
let imperialOrMetric = String::from("imperial");
gyleMaths(startingBrix, desiredCO2Level, finalVolume, imperialOrMetric, &gyleBuilderClone);
}
}
fn gyleMaths(startingBrix: f32, desiredCO2Level: f32, finalVolume: f32, imperialOrMetric: String, ref gyleBuilderClone: &gtk::Builder) {
let startingGravity = brixToGravity(startingBrix);
let finalGravity: f32 = 1.015;
let startingPlato = gravityToPlato(startingGravity);
let finalPlato = gravityToPlato(finalGravity);
let ref gyleOutput: &gtk::Entry = &gyleBuilderClone.get_object("gyleOutput").unwrap();
if imperialOrMetric == "imperial" {
let gyleVolume = ((0.24 * finalVolume * 3.7854 * desiredCO2Level) / (startingPlato - finalPlato)) * 0.2641729;
let total = format!("{:.2} gallons", &gyleVolume);
gyleOutput.set_text(&total);
} else if imperialOrMetric == "metric" {