How do I make the fill padding in std::format dynamic? - rust

To create a format output and pad your output with n you can do something like this in rust:
fn main() {
let title = " Title ";
println!("┌{:─^11}┐", title);
}
That will print:
┌── Title ──┐
So the str is padded (centered via ^) on both sides with - within the space of 11 characters.
How can I make this width dynamic though? Via a variable.

So turns out that's a built-in functionality. std::format comes with a width option indicated with a postfix $.
fn main() {
let title = " Title ";
println!("┌{:─^width$}┐", title, width = 11);
}
This will print:
┌── Title ──┐
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=5666cd7f274d436e2216e7ecd0320072

Related

How to set maximum length in String value DART

i am trying to set maximum length in string value and put '..' instead of removed chrs like following
String myValue = 'Welcome'
now i need the maximum length is 4 so output like following
'welc..'
how can i handle this ? thanks
The short and incorrect version is:
String abbrevBad(String input, int maxlength) {
if (input.length <= maxLength) return input;
return input.substring(0, maxLength - 2) + "..";
}
(Using .. is not the typographical way to mark an elision. That takes ..., the "ellipsis" symbol.)
A more internationally aware version would count grapheme clusters instead of code units, so it handles complex characters and emojis as a single character, and doesn't break in the middle of one. Might also use the proper ellipsis character.
String abbreviate(String input, int maxLength) {
var it = input.characters.iterator;
for (var i = 0; i <= maxLength; i++) {
if (!it.expandNext()) return input;
}
it.dropLast(2);
return "${it.current}\u2026";
}
That also works for characters which are not single code units:
void main() {
print(abbreviate("argelbargle", 7)); // argelb…
print(abbreviate("🇩🇰🇩🇰🇩🇰🇩🇰🇩🇰", 4)); // 🇩🇰🇩🇰🇩🇰…
}
(If you want to use ... instead of …, just change .dropLast(2) to .dropLast(4) and "…" to "...".)
You need to use RichText and you need to specify the overflow type, just like this:
Flexible(
child: RichText("Very, very, very looong text",
overflow: TextOverflow.ellipsis,
),
);
If the Text widget overflows, some points (...) will appears.

SwiftUI: Use of different colours within same Text view

I have a section of text where I am using .replacingOccurrences to display the users' answer within the question sentence:
Text((question.text)
.replacingOccurrences(of: "_____", with:
question.answers[question.userAnswer]
))
.font(Font.custom("ClearSans-Bold", size: 18))
.foregroundColor(.black )
.padding(.bottom, 20)
.multilineTextAlignment(.center)
I want the users' answer question.answers[question.userAnswer] to be a different colour (red/green) to the main body of the text (similar to attached image) however I'm new to SwiftUI so not sure how to add this in.
Image 1
Here's an extension for String that does pretty much what you want:
extension String {
func replacingOccurrences(of: String, with: [Text]) -> Text {
return self.components(separatedBy: of).enumerated().map({(i, s) in
return i < with.count ? Text(s) + with[i] : Text(s)
}).reduce(Text(""), { (r, t) in
return r + t
})
}
}
It uses concatenation of Text elements as George_E suggested. You can use it like this:
struct ContentView: View {
let question: String = "The witch found the concoction extremely _____. _____ makes better ones."
let answers: [String] = ["nauseate", "A friend of her's"]
var body: some View {
question.replacingOccurrences(of: "_____", with: self.answers.map({s in Text(s).foregroundColor(.red)})).foregroundColor(.secondary)
}
}
Result:
You may want to add some extra code for handling cases where the number of answers does not match the occurrences of _____.

How can I 0-pad a number by a variable amount when formatting with std::fmt?

I'm looking to 0-pad a string before I display it to the user, e.g.
let x = 1234;
println!("{:06}", x); // "001234"
However, I'd like the length of the output string to be variable, e.g. it could be set by a command line parameter from the user:
let x = 1234;
let width = 6;
println!("{:0*}", width, x); //fails to compile
// error: invalid format string: expected `'}'`, found `'*'`
Unlike precision, it doesn't seem that 0-padding supports the * for specifying a width.
I'm not looking for solutions that involve manually padding, because it seems awkward to re-implement part of std::fmt.
You can use the :0_ format specifier with a variable:
println!("{:0width$}", x, width = width); // prints 001234
Here it is running in the playground
Likewise, if width <= 4, it just prints 1234. If width = 60, it prints:
000000000000000000000000000000000000000000000000000000001234
The format arguments also support ordinals, thus this also works:
println!("{:01$}", x, width);
The documentation for std::fmt has a rundown of the various parameters and modifiers the print_! macros support.

Swift remove ONLY trailing spaces from string

many examples in SO are fixing both sides, the leading and trailing. My request is only about the trailing.
My input text is: " keep my left side "
Desired output: " keep my left side"
Of course this command will remove both ends:
let cleansed = messageText.trimmingCharacters(in: .whitespacesAndNewlines)
Which won't work for me.
How can I do it?
A quite simple solution is regular expression, the pattern is one or more(+) whitespace characters(\s) at the end of the string($)
let string = " keep my left side "
let cleansed = string.replacingOccurrences(of: "\\s+$",
with: "",
options: .regularExpression)
You can use the rangeOfCharacter function on string with a characterSet. This extension then uses recursion of there are multiple spaces to trim. This will be efficient if you only usually have a small number of spaces.
extension String {
func trailingTrim(_ characterSet : CharacterSet) -> String {
if let range = rangeOfCharacter(from: characterSet, options: [.anchored, .backwards]) {
return self.substring(to: range.lowerBound).trailingTrim(characterSet)
}
return self
}
}
"1234 ".trailingTrim(.whitespaces)
returns
"1234"
Building on vadian's answer I found for Swift 3 at the time of writing that I had to include a range parameter. So:
func trailingTrim(with string : String) -> String {
let start = string.startIndex
let end = string.endIndex
let range: Range<String.Index> = Range<String.Index>(start: start, end: end)
let cleansed:String = string.stringByReplacingOccurrencesOfString("\\s+$",
withString: "",
options: .RegularExpressionSearch,
range: range)
return cleansed
}
Simple. No regular expressions needed.
extension String {
func trimRight() -> String {
let c = reversed().drop(while: { $0.isWhitespace }).reversed()
return String(c)
}
}

How to include emoticons in Swift string?

Here is a pretty good article that references iOS emoticons and their code. For example \ue008 for the small camera.
I tried this in my code :
var myText: String = "\ue008"
This is not accepted by Xcode. How to include it ?
If I understand what you are trying to achieve, then:
Press "ctrl + cmd + space" while in XCode. A sample usage of 'hearts' emoticon
cell.textLabel?.text = "❤️" + " \(liker) liked \(userBeingliked)'s photo"
That's from swift documentation:
let dollarSign = "\u{24}" // $, Unicode scalar U+0024
let blackHeart = "\u{2665}" // ♥, Unicode scalar U+2665
let sparklingHeart = "\u{1F496}" // 💖, Unicode scalar U+1F496
You don't need the unicode constants at all. Just use the character viewer and type the character directly. 😝
let sparklingHeart = "💖"
1 Decoding the Unicode:
extension String {
var decodeEmoji: String{
let data = self.data(using: String.Encoding.utf8);
let decodedStr = NSString(data: data!, encoding: String.Encoding.nonLossyASCII.rawValue)
if let str = decodedStr{
return str as String
}
return self
}
}
Usage
let decodedString = yourString.decodeEmoji
2 Encoding the Unicode:
extension String {
var encodeEmoji: String{
if let encodeStr = NSString(cString: self.cString(using: .nonLossyASCII)!, encoding: String.Encoding.utf8.rawValue){
return encodeStr as String
}
return self
}
}
Usage
let encodedString = yourString.encodeEmoji
You could insert the emoji directly using ⌘ ^ Space.
Or, based on Greg's answer:
var myText: String = "\u{e008}"
As Greg posted above, you can directly input the emoji into Swift using the OSx character viewer. The character viewer is disabled by default. Here is how to enable it:
Go to System Preferences > Language and Region > Keyboard Preferences > Keyboard then check Show Keyboard, Emoji, & Symbol Viewers in menu bar. Once checked you can open the character viewer from the top right menu bar next to your Wifi and Date/Time icons.
from your Hex "0x1F52D" to actual Emoji
let c = 0x1F602
next step would possibly getting an Uint32 from your Hex
let intEmoji = UnicodeScalar(c!).value
from this you can do something like
titleLabel.text = String(UnicodeScalar(intEmoji)!)
here you have a "😂"
it work with range of hexadecimal too
let emojiRanges = [
0x1F600...0x1F636,
0x1F645...0x1F64F,
0x1F910...0x1F91F,
0x1F30D...0x1F52D
]
for range in emojiRanges {
for i in range {
let c = UnicodeScalar(i)!.value
data.append(c)
}
}
to get multiple UInt32 from your Hex range for exemple
Chris Slowik's and Greg's answers are close.
The easiest answer is just to "rephrase" your String from this:
var myText: String = "\ue008"
To this:
var myText: String = "\u{008}"
The Unicodes found on the link you've attached are not wrong, as someone else claimed. You just need to rephrase it inside the String.
The important piece of code in your example above is the "008" part.
I've created a simple function to convert these kinds Unicode to their corresponding Emojis:
func convertHexToEmoji(_ u:Int) -> String {
return "\(UnicodeScalar(u)!)" }
To use:
let myText = convertHexToEmoji(008)
print(myText)
This took me a bit of time to figure out in MacOS 11, so I thought I would share.
If you prefer to input the unicode characters rather than pasting literal emojis, you can find out the unicode for the system emojis like this:
Focus/click into a text field (e.g. the search bar in your web browser).
Press ctrl+cmd+space or go to Edit->Emoji & Symbols in the menu bar.
Scroll up in the character viewer until you see the window expand icon in the upper right:
In the expanded Character Viewer window, press the upper left button and select Customize List....
Scroll down to Code Tables minimized list, expand the list, toggle on Unicode, and press Done (system changed this window to dark mode for whatever reason).
Now, click the different emojis and you should see the unicode underneath the image.
Then you inject it the unicode like this:
var myText: String = "\u{e008}"

Resources